Enable bluetooth a2dpsink to request audio focus from source

- Allow source to initiate play on IoT devices without having audiofocus
  first
- Added mockPackageManager and testSrcPlayIot to A2dpSinkStreamHandler
  unit test

Test: Bluetooth a2dp sink works using the sample-audio-bluetooth
      sample app
Bug: 38098044
Change-Id: I98472c857afa4922ae9ce118c1bcf0f801ffd304
diff --git a/android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkStreamHandler.java b/android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkStreamHandler.java
index 33fe1ec..eb3a827 100644
--- a/android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkStreamHandler.java
+++ b/android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkStreamHandler.java
@@ -17,6 +17,7 @@
 package com.android.bluetooth.a2dpsink;
 
 import android.content.Context;
+import android.content.pm.PackageManager;
 import android.media.AudioAttributes;
 import android.media.AudioManager;
 import android.media.AudioManager.OnAudioFocusChangeListener;
@@ -131,7 +132,16 @@
                 break;
 
             case SRC_PLAY:
-                // Remote play command, if we have audio focus update avrcp, otherwise send pause.
+                // Remote play command.
+                // If is an iot device gain focus and start avrcp updates.
+                if (isIotDevice()) {
+                    if (mAudioFocus == AudioManager.AUDIOFOCUS_NONE) {
+                        requestAudioFocus();
+                    }
+                    startAvrcpUpdates();
+                    break;
+                }
+                // Otherwise, pause if we don't have focus
                 if (mAudioFocus == AudioManager.AUDIOFOCUS_NONE) {
                     sendAvrcpPause();
                 } else {
@@ -311,4 +321,8 @@
             Log.e(TAG, "Passthrough not sent, connection un-available.");
         }
     }
+
+    private boolean isIotDevice() {
+        return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_EMBEDDED);
+    }
 }
diff --git a/android/app/tests/src/com/android/bluetooth/a2dpsink/A2dpSinkStreamHandlerTest.java b/android/app/tests/src/com/android/bluetooth/a2dpsink/A2dpSinkStreamHandlerTest.java
index 2f18960..c611213 100644
--- a/android/app/tests/src/com/android/bluetooth/a2dpsink/A2dpSinkStreamHandlerTest.java
+++ b/android/app/tests/src/com/android/bluetooth/a2dpsink/A2dpSinkStreamHandlerTest.java
@@ -27,6 +27,7 @@
 import static org.mockito.Mockito.when;
 
 import android.content.Context;
+import android.content.pm.PackageManager;
 import android.content.res.Resources;
 import android.media.AudioManager;
 import android.media.AudioManager.OnAudioFocusChangeListener;
@@ -56,6 +57,8 @@
 
     @Mock Resources mockResources;
 
+    @Mock PackageManager mockPackageManager;
+
     @Before
     public void setUp() {
         // Mock the looper
@@ -77,6 +80,8 @@
         when(mockAudioManager.abandonAudioFocus(any())).thenReturn(AudioManager.AUDIOFOCUS_GAIN);
         doNothing().when(mockA2dpSink).informAudioTrackGainNative(anyFloat());
         when(mockContext.getMainLooper()).thenReturn(mHandlerThread.getLooper());
+        when(mockContext.getPackageManager()).thenReturn(mockPackageManager);
+        when(mockPackageManager.hasSystemFeature(any())).thenReturn(false);
 
         streamHandler = spy(new A2dpSinkStreamHandler(mockA2dpSink, mockContext));
     }
@@ -138,6 +143,16 @@
     }
 
     @Test
+    public void testSrcPlayIot() {
+        // Play was pressed remotely for an iot device, expect streaming to start.
+        when(mockPackageManager.hasSystemFeature(any())).thenReturn(true);
+        streamHandler.handleMessage(streamHandler.obtainMessage(A2dpSinkStreamHandler.SRC_PLAY));
+        verify(mockAudioManager, times(1)).requestAudioFocus(any(), anyInt(), anyInt());
+        verify(mockA2dpSink, times(1)).informAudioFocusStateNative(1);
+        verify(mockA2dpSink, times(1)).informAudioTrackGainNative(1.0f);
+    }
+
+    @Test
     public void testSrcPause() {
         // Play was pressed locally, expect streaming to start.
         streamHandler.handleMessage(streamHandler.obtainMessage(A2dpSinkStreamHandler.SRC_PLAY));