A2DP Sink: Focus gain while transient loss

While Bluetooth is under a transient focus loss if the user presses the
play button, Bluetooth should attempt to regain audio focus rather than
just wait passive for the transient holder to release it.

Bug: 143916073
Test: atest A2dpSinkStreamHandlerTest
Change-Id: I7b958a9ff06c9f1fcb9383a3a40ca147f4ad9399
(cherry picked from commit 97e20beea72e7b717465cb280ef576f5f2e29711)

Merged-In: I7b958a9ff06c9f1fcb9383a3a40ca147f4ad9399
Change-Id: I78dfe8917d02c4b9d71d82db4fae586f52612050
diff --git a/src/com/android/bluetooth/a2dpsink/A2dpSinkStreamHandler.java b/src/com/android/bluetooth/a2dpsink/A2dpSinkStreamHandler.java
index ffd648a..87ccfc8 100644
--- a/src/com/android/bluetooth/a2dpsink/A2dpSinkStreamHandler.java
+++ b/src/com/android/bluetooth/a2dpsink/A2dpSinkStreamHandler.java
@@ -183,8 +183,9 @@
                 break;
 
             case AUDIO_FOCUS_CHANGE:
+                mAudioFocus = (int) message.obj;
                 // message.obj is the newly granted audio focus.
-                switch ((int) message.obj) {
+                switch (mAudioFocus) {
                     case AudioManager.AUDIOFOCUS_GAIN:
                         removeMessages(DELAYED_PAUSE);
                         // Begin playing audio, if we paused the remote, send a play now.
@@ -245,7 +246,7 @@
      */
     private void requestAudioFocusIfNone() {
         if (DBG) Log.d(TAG, "requestAudioFocusIfNone()");
-        if (mAudioFocus == AudioManager.AUDIOFOCUS_NONE) {
+        if (mAudioFocus != AudioManager.AUDIOFOCUS_GAIN) {
             requestAudioFocus();
         }
         // On the off change mMediaPlayer errors out and dies, we want to make sure we retry this.
diff --git a/tests/unit/src/com/android/bluetooth/a2dpsink/A2dpSinkStreamHandlerTest.java b/tests/unit/src/com/android/bluetooth/a2dpsink/A2dpSinkStreamHandlerTest.java
index c759a8a..b8fbbb9 100644
--- a/tests/unit/src/com/android/bluetooth/a2dpsink/A2dpSinkStreamHandlerTest.java
+++ b/tests/unit/src/com/android/bluetooth/a2dpsink/A2dpSinkStreamHandlerTest.java
@@ -195,6 +195,21 @@
     }
 
     @Test
+    public void testFocusRerequest() {
+        // Focus was lost transiently, expect streaming to stop.
+        testSnkPlay();
+        mStreamHandler.handleMessage(
+                mStreamHandler.obtainMessage(A2dpSinkStreamHandler.AUDIO_FOCUS_CHANGE,
+                        AudioManager.AUDIOFOCUS_LOSS_TRANSIENT));
+        verify(mMockAudioManager, times(0)).abandonAudioFocus(any());
+        verify(mMockA2dpSink, times(0)).informAudioFocusStateNative(0);
+        verify(mMockA2dpSink, times(1)).informAudioTrackGainNative(0);
+        mStreamHandler.handleMessage(
+                mStreamHandler.obtainMessage(A2dpSinkStreamHandler.REQUEST_FOCUS, true));
+        verify(mMockAudioManager, times(2)).requestAudioFocus(any());
+    }
+
+    @Test
     public void testFocusGainTransient() {
         // Focus was lost then regained.
         testSnkPlay();