Loading android/app/src/com/android/bluetooth/btservice/PhonePolicy.java +19 −9 Original line number Diff line number Diff line Loading @@ -80,13 +80,15 @@ class PhonePolicy { private static final int MESSAGE_ADAPTER_STATE_TURNED_ON = 4; // Timeouts private static final int CONNECT_OTHER_PROFILES_TIMEOUT = 6000; // 6s @VisibleForTesting static int sConnectOtherProfilesTimeoutMillis = 6000; // 6s private final AdapterService mAdapterService; private final ServiceFactory mFactory; private final Handler mHandler; private final HashSet<BluetoothDevice> mHeadsetRetrySet = new HashSet<>(); private final HashSet<BluetoothDevice> mA2dpRetrySet = new HashSet<>(); private final HashSet<BluetoothDevice> mConnectOtherProfilesDeviceSet = new HashSet<>(); // Broadcast receiver for all changes to states of various profiles private final BroadcastReceiver mReceiver = new BroadcastReceiver() { Loading Loading @@ -167,12 +169,14 @@ class PhonePolicy { } break; case MESSAGE_CONNECT_OTHER_PROFILES: case MESSAGE_CONNECT_OTHER_PROFILES: { // Called when we try connect some profiles in processConnectOtherProfiles but // we send a delayed message to try connecting the remaining profiles processConnectOtherProfiles((BluetoothDevice) msg.obj); BluetoothDevice device = (BluetoothDevice) msg.obj; processConnectOtherProfiles(device); mConnectOtherProfilesDeviceSet.remove(device); break; } case MESSAGE_ADAPTER_STATE_TURNED_ON: // Call auto connect when adapter switches state to ON resetStates(); Loading Loading @@ -341,12 +345,18 @@ class PhonePolicy { } private void connectOtherProfile(BluetoothDevice device) { if ((!mHandler.hasMessages(MESSAGE_CONNECT_OTHER_PROFILES)) && (!mAdapterService.isQuietModeEnabled())) { if (mAdapterService.isQuietModeEnabled()) { debugLog("connectOtherProfile: in quiet mode, skip connect other profile " + device); return; } if (mConnectOtherProfilesDeviceSet.contains(device)) { debugLog("connectOtherProfile: already scheduled callback for " + device); return; } mConnectOtherProfilesDeviceSet.add(device); Message m = mHandler.obtainMessage(MESSAGE_CONNECT_OTHER_PROFILES); m.obj = device; mHandler.sendMessageDelayed(m, CONNECT_OTHER_PROFILES_TIMEOUT); } mHandler.sendMessageDelayed(m, sConnectOtherProfilesTimeoutMillis); } // This function is called whenever a profile is connected. This allows any other bluetooth Loading android/app/tests/unit/src/com/android/bluetooth/btservice/PhonePolicyTest.java +57 −73 Original line number Diff line number Diff line Loading @@ -28,8 +28,6 @@ import android.content.BroadcastReceiver; import android.content.Intent; import android.os.HandlerThread; import android.os.ParcelUuid; import android.os.TestLooperManager; import android.support.test.InstrumentationRegistry; import android.support.test.filters.MediumTest; import android.support.test.runner.AndroidJUnit4; Loading @@ -50,11 +48,15 @@ import java.util.ArrayList; @RunWith(AndroidJUnit4.class) public class PhonePolicyTest { private static final int MAX_CONNECTED_AUDIO_DEVICES = 5; private static final int ASYNC_CALL_TIMEOUT_MILLIS = 250; private static final int CONNECT_OTHER_PROFILES_TIMEOUT_MILLIS = 1000; private static final int CONNECT_OTHER_PROFILES_TIMEOUT_WAIT_MILLIS = CONNECT_OTHER_PROFILES_TIMEOUT_MILLIS * 3 / 2; private HandlerThread mHandlerThread; private TestLooperManager mTestLooperManager; private BluetoothAdapter mAdapter; private BluetoothDevice mTestDevice; private PhonePolicy mPhonePolicy; @Mock private AdapterService mAdapterService; @Mock private ServiceFactory mServiceFactory; Loading @@ -74,20 +76,19 @@ public class PhonePolicyTest { // Start handler thread for this test mHandlerThread = new HandlerThread("PhonePolicyTestHandlerThread"); mHandlerThread.start(); mTestLooperManager = InstrumentationRegistry.getInstrumentation() .acquireLooperManager(mHandlerThread.getLooper()); // Mock the looper doReturn(mHandlerThread.getLooper()).when(mAdapterService).getMainLooper(); // Tell the AdapterService that it is a mock (see isMock documentation) doReturn(true).when(mAdapterService).isMock(); // Must be called to initialize services mAdapter = BluetoothAdapter.getDefaultAdapter(); mTestDevice = mAdapter.getRemoteDevice("00:01:02:03:04:05"); mTestDevice = TestUtils.getTestDevice(mAdapter, 1); PhonePolicy.sConnectOtherProfilesTimeoutMillis = CONNECT_OTHER_PROFILES_TIMEOUT_MILLIS; mPhonePolicy = new PhonePolicy(mAdapterService, mServiceFactory); } @After public void tearDown() throws Exception { mTestLooperManager.release(); mHandlerThread.quit(); TestUtils.clearAdapterService(mAdapterService); } Loading @@ -106,26 +107,19 @@ public class PhonePolicyTest { // Mock the A2DP service to return undefined priority when(mA2dpService.getPriority(mTestDevice)).thenReturn(BluetoothProfile.PRIORITY_UNDEFINED); PhonePolicy phPol = new PhonePolicy(mAdapterService, mServiceFactory); // Get the broadcast receiver to inject events. BroadcastReceiver injector = phPol.getBroadcastReceiver(); // Inject an event for UUIDs updated for a remote device with only HFP enabled Intent intent = new Intent(BluetoothDevice.ACTION_UUID); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mTestDevice); ParcelUuid[] uuids = new ParcelUuid[2]; uuids[0] = BluetoothUuid.Handsfree; uuids[1] = BluetoothUuid.AudioSink; intent.putExtra(BluetoothDevice.EXTRA_UUID, uuids); injector.onReceive(null /* context */, intent); mPhonePolicy.getBroadcastReceiver().onReceive(null /* context */, intent); // Check that the priorities of the devices for preferred profiles are set to ON executePendingMessages(1); verify(mHeadsetService, times(1)).setPriority(eq(mTestDevice), verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).setPriority(eq(mTestDevice), eq(BluetoothProfile.PRIORITY_ON)); verify(mA2dpService, times(1)).setPriority(eq(mTestDevice), verify(mA2dpService, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).setPriority(eq(mTestDevice), eq(BluetoothProfile.PRIORITY_ON)); } Loading @@ -152,20 +146,14 @@ public class PhonePolicyTest { when(mA2dpService.getPriority(mTestDevice)).thenReturn( BluetoothProfile.PRIORITY_AUTO_CONNECT); PhonePolicy phPol = new PhonePolicy(mAdapterService, mServiceFactory); // Get the broadcast receiver to inject events BroadcastReceiver injector = phPol.getBroadcastReceiver(); // Inject an event that the adapter is turned on. Intent intent = new Intent(BluetoothAdapter.ACTION_STATE_CHANGED); intent.putExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.STATE_ON); injector.onReceive(null /* context */, intent); mPhonePolicy.getBroadcastReceiver().onReceive(null /* context */, intent); // Check that we got a request to connect over HFP and A2DP executePendingMessages(1); verify(mHeadsetService, times(1)).connect(eq(mTestDevice)); verify(mA2dpService, times(1)).connect(eq(mTestDevice)); verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).connect(eq(mTestDevice)); verify(mA2dpService, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).connect(eq(mTestDevice)); } /** Loading @@ -188,8 +176,6 @@ public class PhonePolicyTest { when(mAdapterService.getState()).thenReturn(BluetoothAdapter.STATE_ON); PhonePolicy phPol = new PhonePolicy(mAdapterService, mServiceFactory); // We want to trigger (in CONNECT_OTHER_PROFILES_TIMEOUT) a call to connect A2DP // To enable that we need to make sure that HeadsetService returns the device as list of // connected devices Loading @@ -200,9 +186,6 @@ public class PhonePolicyTest { when(mA2dpService.getConnectionState(mTestDevice)).thenReturn( BluetoothProfile.STATE_DISCONNECTED); // Get the broadcast receiver to inject events BroadcastReceiver injector = phPol.getBroadcastReceiver(); // We send a connection successful for one profile since the re-connect *only* works if we // have already connected successfully over one of the profiles Intent intent = new Intent(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED); Loading @@ -210,11 +193,11 @@ public class PhonePolicyTest { intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, BluetoothProfile.STATE_DISCONNECTED); intent.putExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_CONNECTED); intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); injector.onReceive(null /* context */, intent); mPhonePolicy.getBroadcastReceiver().onReceive(null /* context */, intent); // Check that we get a call to A2DP connect executePendingMessages(2); verify(mA2dpService, times(1)).connect(eq(mTestDevice)); verify(mA2dpService, timeout(CONNECT_OTHER_PROFILES_TIMEOUT_WAIT_MILLIS)).connect( eq(mTestDevice)); } /** Loading @@ -222,11 +205,12 @@ public class PhonePolicyTest { */ @Test public void testAutoConnectMultipleDevices() { final int kMaxTestDevices = 2; final int kMaxTestDevices = 3; BluetoothDevice[] testDevices = new BluetoothDevice[kMaxTestDevices]; ArrayList<BluetoothDevice> hsConnectedDevices = new ArrayList<>(); ArrayList<BluetoothDevice> a2dpConnectedDevices = new ArrayList<>(); BluetoothDevice a2dpNotConnectedDevice = null; BluetoothDevice a2dpNotConnectedDevice1 = null; BluetoothDevice a2dpNotConnectedDevice2 = null; for (int i = 0; i < kMaxTestDevices; i++) { BluetoothDevice testDevice = TestUtils.getTestDevice(mAdapter, i); Loading @@ -243,36 +227,46 @@ public class PhonePolicyTest { // of connected devices. hsConnectedDevices.add(testDevice); // Connect A2DP for all devices except the last one if (i < kMaxTestDevices - 1) { if (i < (kMaxTestDevices - 2)) { a2dpConnectedDevices.add(testDevice); } else { a2dpNotConnectedDevice = testDevice; } } a2dpNotConnectedDevice1 = hsConnectedDevices.get(kMaxTestDevices - 1); a2dpNotConnectedDevice2 = hsConnectedDevices.get(kMaxTestDevices - 2); when(mAdapterService.getBondedDevices()).thenReturn(testDevices); when(mAdapterService.getState()).thenReturn(BluetoothAdapter.STATE_ON); when(mHeadsetService.getConnectedDevices()).thenReturn(hsConnectedDevices); when(mA2dpService.getConnectedDevices()).thenReturn(a2dpConnectedDevices); // One of the A2DP devices is not connected when(mA2dpService.getConnectionState(a2dpNotConnectedDevice)).thenReturn( // Two of the A2DP devices are not connected when(mA2dpService.getConnectionState(a2dpNotConnectedDevice1)).thenReturn( BluetoothProfile.STATE_DISCONNECTED); when(mA2dpService.getConnectionState(a2dpNotConnectedDevice2)).thenReturn( BluetoothProfile.STATE_DISCONNECTED); // Get the broadcast receiver to inject events PhonePolicy phPol = new PhonePolicy(mAdapterService, mServiceFactory); BroadcastReceiver injector = phPol.getBroadcastReceiver(); // We send a connection successful for one profile since the re-connect *only* works if we // have already connected successfully over one of the profiles Intent intent = new Intent(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, a2dpNotConnectedDevice); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, a2dpNotConnectedDevice1); intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, BluetoothProfile.STATE_DISCONNECTED); intent.putExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_CONNECTED); intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); injector.onReceive(null /* context */, intent); mPhonePolicy.getBroadcastReceiver().onReceive(null /* context */, intent); // We send a connection successful for one profile since the re-connect *only* works if we // have already connected successfully over one of the profiles intent = new Intent(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, a2dpNotConnectedDevice2); intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, BluetoothProfile.STATE_DISCONNECTED); intent.putExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_CONNECTED); intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); mPhonePolicy.getBroadcastReceiver().onReceive(null /* context */, intent); // Check that we get a call to A2DP connect executePendingMessages(2); verify(mA2dpService, times(1)).connect(eq(a2dpNotConnectedDevice)); verify(mA2dpService, timeout(CONNECT_OTHER_PROFILES_TIMEOUT_WAIT_MILLIS)).connect( eq(a2dpNotConnectedDevice1)); verify(mA2dpService, timeout(CONNECT_OTHER_PROFILES_TIMEOUT_WAIT_MILLIS)).connect( eq(a2dpNotConnectedDevice2)); } /** Loading Loading @@ -312,22 +306,19 @@ public class PhonePolicyTest { hsConnectedDevices.add(testDevice); when(mHeadsetService.getPriority(testDevice)).thenReturn( BluetoothProfile.PRIORITY_ON); when(mA2dpService.getPriority(testDevice)).thenReturn( BluetoothProfile.PRIORITY_ON); when(mA2dpService.getPriority(testDevice)).thenReturn(BluetoothProfile.PRIORITY_ON); } if (i == 2) { a2dpConnectedDevices.add(testDevice); when(mHeadsetService.getPriority(testDevice)).thenReturn( BluetoothProfile.PRIORITY_ON); when(mA2dpService.getPriority(testDevice)).thenReturn( BluetoothProfile.PRIORITY_ON); when(mA2dpService.getPriority(testDevice)).thenReturn(BluetoothProfile.PRIORITY_ON); } if (i == 3) { // Device not connected when(mHeadsetService.getPriority(testDevice)).thenReturn( BluetoothProfile.PRIORITY_ON); when(mA2dpService.getPriority(testDevice)).thenReturn( BluetoothProfile.PRIORITY_ON); when(mA2dpService.getPriority(testDevice)).thenReturn(BluetoothProfile.PRIORITY_ON); } } when(mAdapterService.getBondedDevices()).thenReturn(testDevices); Loading Loading @@ -369,8 +360,8 @@ public class PhonePolicyTest { intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); injector.onReceive(null /* context */, intent); // Check that we get a call to A2DP connect executePendingMessages(2); verify(mA2dpService, times(1)).connect(eq(testDevices[1])); verify(mA2dpService, timeout(CONNECT_OTHER_PROFILES_TIMEOUT_WAIT_MILLIS)).connect( eq(testDevices[1])); // testDevices[1] auto-connect completed for A2DP a2dpConnectedDevices.add(testDevices[1]); Loading Loading @@ -404,8 +395,8 @@ public class PhonePolicyTest { intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); injector.onReceive(null /* context */, intent); // Check that we get a call to HFP connect executePendingMessages(2); verify(mHeadsetService, times(1)).connect(eq(testDevices[2])); verify(mHeadsetService, timeout(CONNECT_OTHER_PROFILES_TIMEOUT_WAIT_MILLIS)).connect( eq(testDevices[2])); // testDevices[2] auto-connect completed for HFP hsConnectedDevices.add(testDevices[2]); Loading Loading @@ -473,8 +464,8 @@ public class PhonePolicyTest { injector.onReceive(null /* context */, intent); // Check that we don't get any calls to reconnect executePendingMessages(1); verify(mA2dpService, never()).connect(eq(mTestDevice)); verify(mA2dpService, after(CONNECT_OTHER_PROFILES_TIMEOUT_WAIT_MILLIS).never()).connect( eq(mTestDevice)); verify(mHeadsetService, never()).connect(eq(mTestDevice)); } Loading Loading @@ -504,17 +495,10 @@ public class PhonePolicyTest { injector.onReceive(null /* context */, intent); // Check that we do not crash and not call any setPriority methods executePendingMessages(1); verify(mHeadsetService, never()).setPriority(eq(mTestDevice), eq(BluetoothProfile.PRIORITY_ON)); verify(mHeadsetService, after(CONNECT_OTHER_PROFILES_TIMEOUT_WAIT_MILLIS).never()).setPriority( eq(mTestDevice), eq(BluetoothProfile.PRIORITY_ON)); verify(mA2dpService, never()).setPriority(eq(mTestDevice), eq(BluetoothProfile.PRIORITY_ON)); } private void executePendingMessages(int numMessage) { while (numMessage > 0) { mTestLooperManager.execute(mTestLooperManager.next()); numMessage--; } } } Loading
android/app/src/com/android/bluetooth/btservice/PhonePolicy.java +19 −9 Original line number Diff line number Diff line Loading @@ -80,13 +80,15 @@ class PhonePolicy { private static final int MESSAGE_ADAPTER_STATE_TURNED_ON = 4; // Timeouts private static final int CONNECT_OTHER_PROFILES_TIMEOUT = 6000; // 6s @VisibleForTesting static int sConnectOtherProfilesTimeoutMillis = 6000; // 6s private final AdapterService mAdapterService; private final ServiceFactory mFactory; private final Handler mHandler; private final HashSet<BluetoothDevice> mHeadsetRetrySet = new HashSet<>(); private final HashSet<BluetoothDevice> mA2dpRetrySet = new HashSet<>(); private final HashSet<BluetoothDevice> mConnectOtherProfilesDeviceSet = new HashSet<>(); // Broadcast receiver for all changes to states of various profiles private final BroadcastReceiver mReceiver = new BroadcastReceiver() { Loading Loading @@ -167,12 +169,14 @@ class PhonePolicy { } break; case MESSAGE_CONNECT_OTHER_PROFILES: case MESSAGE_CONNECT_OTHER_PROFILES: { // Called when we try connect some profiles in processConnectOtherProfiles but // we send a delayed message to try connecting the remaining profiles processConnectOtherProfiles((BluetoothDevice) msg.obj); BluetoothDevice device = (BluetoothDevice) msg.obj; processConnectOtherProfiles(device); mConnectOtherProfilesDeviceSet.remove(device); break; } case MESSAGE_ADAPTER_STATE_TURNED_ON: // Call auto connect when adapter switches state to ON resetStates(); Loading Loading @@ -341,12 +345,18 @@ class PhonePolicy { } private void connectOtherProfile(BluetoothDevice device) { if ((!mHandler.hasMessages(MESSAGE_CONNECT_OTHER_PROFILES)) && (!mAdapterService.isQuietModeEnabled())) { if (mAdapterService.isQuietModeEnabled()) { debugLog("connectOtherProfile: in quiet mode, skip connect other profile " + device); return; } if (mConnectOtherProfilesDeviceSet.contains(device)) { debugLog("connectOtherProfile: already scheduled callback for " + device); return; } mConnectOtherProfilesDeviceSet.add(device); Message m = mHandler.obtainMessage(MESSAGE_CONNECT_OTHER_PROFILES); m.obj = device; mHandler.sendMessageDelayed(m, CONNECT_OTHER_PROFILES_TIMEOUT); } mHandler.sendMessageDelayed(m, sConnectOtherProfilesTimeoutMillis); } // This function is called whenever a profile is connected. This allows any other bluetooth Loading
android/app/tests/unit/src/com/android/bluetooth/btservice/PhonePolicyTest.java +57 −73 Original line number Diff line number Diff line Loading @@ -28,8 +28,6 @@ import android.content.BroadcastReceiver; import android.content.Intent; import android.os.HandlerThread; import android.os.ParcelUuid; import android.os.TestLooperManager; import android.support.test.InstrumentationRegistry; import android.support.test.filters.MediumTest; import android.support.test.runner.AndroidJUnit4; Loading @@ -50,11 +48,15 @@ import java.util.ArrayList; @RunWith(AndroidJUnit4.class) public class PhonePolicyTest { private static final int MAX_CONNECTED_AUDIO_DEVICES = 5; private static final int ASYNC_CALL_TIMEOUT_MILLIS = 250; private static final int CONNECT_OTHER_PROFILES_TIMEOUT_MILLIS = 1000; private static final int CONNECT_OTHER_PROFILES_TIMEOUT_WAIT_MILLIS = CONNECT_OTHER_PROFILES_TIMEOUT_MILLIS * 3 / 2; private HandlerThread mHandlerThread; private TestLooperManager mTestLooperManager; private BluetoothAdapter mAdapter; private BluetoothDevice mTestDevice; private PhonePolicy mPhonePolicy; @Mock private AdapterService mAdapterService; @Mock private ServiceFactory mServiceFactory; Loading @@ -74,20 +76,19 @@ public class PhonePolicyTest { // Start handler thread for this test mHandlerThread = new HandlerThread("PhonePolicyTestHandlerThread"); mHandlerThread.start(); mTestLooperManager = InstrumentationRegistry.getInstrumentation() .acquireLooperManager(mHandlerThread.getLooper()); // Mock the looper doReturn(mHandlerThread.getLooper()).when(mAdapterService).getMainLooper(); // Tell the AdapterService that it is a mock (see isMock documentation) doReturn(true).when(mAdapterService).isMock(); // Must be called to initialize services mAdapter = BluetoothAdapter.getDefaultAdapter(); mTestDevice = mAdapter.getRemoteDevice("00:01:02:03:04:05"); mTestDevice = TestUtils.getTestDevice(mAdapter, 1); PhonePolicy.sConnectOtherProfilesTimeoutMillis = CONNECT_OTHER_PROFILES_TIMEOUT_MILLIS; mPhonePolicy = new PhonePolicy(mAdapterService, mServiceFactory); } @After public void tearDown() throws Exception { mTestLooperManager.release(); mHandlerThread.quit(); TestUtils.clearAdapterService(mAdapterService); } Loading @@ -106,26 +107,19 @@ public class PhonePolicyTest { // Mock the A2DP service to return undefined priority when(mA2dpService.getPriority(mTestDevice)).thenReturn(BluetoothProfile.PRIORITY_UNDEFINED); PhonePolicy phPol = new PhonePolicy(mAdapterService, mServiceFactory); // Get the broadcast receiver to inject events. BroadcastReceiver injector = phPol.getBroadcastReceiver(); // Inject an event for UUIDs updated for a remote device with only HFP enabled Intent intent = new Intent(BluetoothDevice.ACTION_UUID); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mTestDevice); ParcelUuid[] uuids = new ParcelUuid[2]; uuids[0] = BluetoothUuid.Handsfree; uuids[1] = BluetoothUuid.AudioSink; intent.putExtra(BluetoothDevice.EXTRA_UUID, uuids); injector.onReceive(null /* context */, intent); mPhonePolicy.getBroadcastReceiver().onReceive(null /* context */, intent); // Check that the priorities of the devices for preferred profiles are set to ON executePendingMessages(1); verify(mHeadsetService, times(1)).setPriority(eq(mTestDevice), verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).setPriority(eq(mTestDevice), eq(BluetoothProfile.PRIORITY_ON)); verify(mA2dpService, times(1)).setPriority(eq(mTestDevice), verify(mA2dpService, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).setPriority(eq(mTestDevice), eq(BluetoothProfile.PRIORITY_ON)); } Loading @@ -152,20 +146,14 @@ public class PhonePolicyTest { when(mA2dpService.getPriority(mTestDevice)).thenReturn( BluetoothProfile.PRIORITY_AUTO_CONNECT); PhonePolicy phPol = new PhonePolicy(mAdapterService, mServiceFactory); // Get the broadcast receiver to inject events BroadcastReceiver injector = phPol.getBroadcastReceiver(); // Inject an event that the adapter is turned on. Intent intent = new Intent(BluetoothAdapter.ACTION_STATE_CHANGED); intent.putExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.STATE_ON); injector.onReceive(null /* context */, intent); mPhonePolicy.getBroadcastReceiver().onReceive(null /* context */, intent); // Check that we got a request to connect over HFP and A2DP executePendingMessages(1); verify(mHeadsetService, times(1)).connect(eq(mTestDevice)); verify(mA2dpService, times(1)).connect(eq(mTestDevice)); verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).connect(eq(mTestDevice)); verify(mA2dpService, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).connect(eq(mTestDevice)); } /** Loading @@ -188,8 +176,6 @@ public class PhonePolicyTest { when(mAdapterService.getState()).thenReturn(BluetoothAdapter.STATE_ON); PhonePolicy phPol = new PhonePolicy(mAdapterService, mServiceFactory); // We want to trigger (in CONNECT_OTHER_PROFILES_TIMEOUT) a call to connect A2DP // To enable that we need to make sure that HeadsetService returns the device as list of // connected devices Loading @@ -200,9 +186,6 @@ public class PhonePolicyTest { when(mA2dpService.getConnectionState(mTestDevice)).thenReturn( BluetoothProfile.STATE_DISCONNECTED); // Get the broadcast receiver to inject events BroadcastReceiver injector = phPol.getBroadcastReceiver(); // We send a connection successful for one profile since the re-connect *only* works if we // have already connected successfully over one of the profiles Intent intent = new Intent(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED); Loading @@ -210,11 +193,11 @@ public class PhonePolicyTest { intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, BluetoothProfile.STATE_DISCONNECTED); intent.putExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_CONNECTED); intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); injector.onReceive(null /* context */, intent); mPhonePolicy.getBroadcastReceiver().onReceive(null /* context */, intent); // Check that we get a call to A2DP connect executePendingMessages(2); verify(mA2dpService, times(1)).connect(eq(mTestDevice)); verify(mA2dpService, timeout(CONNECT_OTHER_PROFILES_TIMEOUT_WAIT_MILLIS)).connect( eq(mTestDevice)); } /** Loading @@ -222,11 +205,12 @@ public class PhonePolicyTest { */ @Test public void testAutoConnectMultipleDevices() { final int kMaxTestDevices = 2; final int kMaxTestDevices = 3; BluetoothDevice[] testDevices = new BluetoothDevice[kMaxTestDevices]; ArrayList<BluetoothDevice> hsConnectedDevices = new ArrayList<>(); ArrayList<BluetoothDevice> a2dpConnectedDevices = new ArrayList<>(); BluetoothDevice a2dpNotConnectedDevice = null; BluetoothDevice a2dpNotConnectedDevice1 = null; BluetoothDevice a2dpNotConnectedDevice2 = null; for (int i = 0; i < kMaxTestDevices; i++) { BluetoothDevice testDevice = TestUtils.getTestDevice(mAdapter, i); Loading @@ -243,36 +227,46 @@ public class PhonePolicyTest { // of connected devices. hsConnectedDevices.add(testDevice); // Connect A2DP for all devices except the last one if (i < kMaxTestDevices - 1) { if (i < (kMaxTestDevices - 2)) { a2dpConnectedDevices.add(testDevice); } else { a2dpNotConnectedDevice = testDevice; } } a2dpNotConnectedDevice1 = hsConnectedDevices.get(kMaxTestDevices - 1); a2dpNotConnectedDevice2 = hsConnectedDevices.get(kMaxTestDevices - 2); when(mAdapterService.getBondedDevices()).thenReturn(testDevices); when(mAdapterService.getState()).thenReturn(BluetoothAdapter.STATE_ON); when(mHeadsetService.getConnectedDevices()).thenReturn(hsConnectedDevices); when(mA2dpService.getConnectedDevices()).thenReturn(a2dpConnectedDevices); // One of the A2DP devices is not connected when(mA2dpService.getConnectionState(a2dpNotConnectedDevice)).thenReturn( // Two of the A2DP devices are not connected when(mA2dpService.getConnectionState(a2dpNotConnectedDevice1)).thenReturn( BluetoothProfile.STATE_DISCONNECTED); when(mA2dpService.getConnectionState(a2dpNotConnectedDevice2)).thenReturn( BluetoothProfile.STATE_DISCONNECTED); // Get the broadcast receiver to inject events PhonePolicy phPol = new PhonePolicy(mAdapterService, mServiceFactory); BroadcastReceiver injector = phPol.getBroadcastReceiver(); // We send a connection successful for one profile since the re-connect *only* works if we // have already connected successfully over one of the profiles Intent intent = new Intent(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, a2dpNotConnectedDevice); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, a2dpNotConnectedDevice1); intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, BluetoothProfile.STATE_DISCONNECTED); intent.putExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_CONNECTED); intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); injector.onReceive(null /* context */, intent); mPhonePolicy.getBroadcastReceiver().onReceive(null /* context */, intent); // We send a connection successful for one profile since the re-connect *only* works if we // have already connected successfully over one of the profiles intent = new Intent(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, a2dpNotConnectedDevice2); intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, BluetoothProfile.STATE_DISCONNECTED); intent.putExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_CONNECTED); intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); mPhonePolicy.getBroadcastReceiver().onReceive(null /* context */, intent); // Check that we get a call to A2DP connect executePendingMessages(2); verify(mA2dpService, times(1)).connect(eq(a2dpNotConnectedDevice)); verify(mA2dpService, timeout(CONNECT_OTHER_PROFILES_TIMEOUT_WAIT_MILLIS)).connect( eq(a2dpNotConnectedDevice1)); verify(mA2dpService, timeout(CONNECT_OTHER_PROFILES_TIMEOUT_WAIT_MILLIS)).connect( eq(a2dpNotConnectedDevice2)); } /** Loading Loading @@ -312,22 +306,19 @@ public class PhonePolicyTest { hsConnectedDevices.add(testDevice); when(mHeadsetService.getPriority(testDevice)).thenReturn( BluetoothProfile.PRIORITY_ON); when(mA2dpService.getPriority(testDevice)).thenReturn( BluetoothProfile.PRIORITY_ON); when(mA2dpService.getPriority(testDevice)).thenReturn(BluetoothProfile.PRIORITY_ON); } if (i == 2) { a2dpConnectedDevices.add(testDevice); when(mHeadsetService.getPriority(testDevice)).thenReturn( BluetoothProfile.PRIORITY_ON); when(mA2dpService.getPriority(testDevice)).thenReturn( BluetoothProfile.PRIORITY_ON); when(mA2dpService.getPriority(testDevice)).thenReturn(BluetoothProfile.PRIORITY_ON); } if (i == 3) { // Device not connected when(mHeadsetService.getPriority(testDevice)).thenReturn( BluetoothProfile.PRIORITY_ON); when(mA2dpService.getPriority(testDevice)).thenReturn( BluetoothProfile.PRIORITY_ON); when(mA2dpService.getPriority(testDevice)).thenReturn(BluetoothProfile.PRIORITY_ON); } } when(mAdapterService.getBondedDevices()).thenReturn(testDevices); Loading Loading @@ -369,8 +360,8 @@ public class PhonePolicyTest { intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); injector.onReceive(null /* context */, intent); // Check that we get a call to A2DP connect executePendingMessages(2); verify(mA2dpService, times(1)).connect(eq(testDevices[1])); verify(mA2dpService, timeout(CONNECT_OTHER_PROFILES_TIMEOUT_WAIT_MILLIS)).connect( eq(testDevices[1])); // testDevices[1] auto-connect completed for A2DP a2dpConnectedDevices.add(testDevices[1]); Loading Loading @@ -404,8 +395,8 @@ public class PhonePolicyTest { intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); injector.onReceive(null /* context */, intent); // Check that we get a call to HFP connect executePendingMessages(2); verify(mHeadsetService, times(1)).connect(eq(testDevices[2])); verify(mHeadsetService, timeout(CONNECT_OTHER_PROFILES_TIMEOUT_WAIT_MILLIS)).connect( eq(testDevices[2])); // testDevices[2] auto-connect completed for HFP hsConnectedDevices.add(testDevices[2]); Loading Loading @@ -473,8 +464,8 @@ public class PhonePolicyTest { injector.onReceive(null /* context */, intent); // Check that we don't get any calls to reconnect executePendingMessages(1); verify(mA2dpService, never()).connect(eq(mTestDevice)); verify(mA2dpService, after(CONNECT_OTHER_PROFILES_TIMEOUT_WAIT_MILLIS).never()).connect( eq(mTestDevice)); verify(mHeadsetService, never()).connect(eq(mTestDevice)); } Loading Loading @@ -504,17 +495,10 @@ public class PhonePolicyTest { injector.onReceive(null /* context */, intent); // Check that we do not crash and not call any setPriority methods executePendingMessages(1); verify(mHeadsetService, never()).setPriority(eq(mTestDevice), eq(BluetoothProfile.PRIORITY_ON)); verify(mHeadsetService, after(CONNECT_OTHER_PROFILES_TIMEOUT_WAIT_MILLIS).never()).setPriority( eq(mTestDevice), eq(BluetoothProfile.PRIORITY_ON)); verify(mA2dpService, never()).setPriority(eq(mTestDevice), eq(BluetoothProfile.PRIORITY_ON)); } private void executePendingMessages(int numMessage) { while (numMessage > 0) { mTestLooperManager.execute(mTestLooperManager.next()); numMessage--; } } }