Loading android/app/src/com/android/bluetooth/pbapclient/PbapClientService.java +5 −12 Original line number Diff line number Diff line Loading @@ -35,7 +35,6 @@ import android.provider.CallLog; import android.sysprop.BluetoothProperties; import android.util.Log; import com.android.bluetooth.BluetoothMethodProxy; import com.android.bluetooth.R; import com.android.bluetooth.btservice.AdapterService; import com.android.bluetooth.btservice.ProfileService; Loading Loading @@ -297,11 +296,10 @@ public class PbapClientService extends ProfileService { } } private void removeHfpCallLog(String accountName, Context context) { private void removeHfpCallLog(String accountName) { Log.d(TAG, "Removing call logs from " + accountName); // Delete call logs belonging to accountName==BD_ADDR that also match // component name "hfpclient". ComponentName componentName = new ComponentName(context, HfpClientConnectionService.class); // Delete call logs belonging to accountName==BD_ADDR that also match component "hfpclient" ComponentName componentName = new ComponentName(this, HfpClientConnectionService.class); String selectionFilter = CallLog.Calls.PHONE_ACCOUNT_ID + "=? AND " Loading @@ -309,12 +307,7 @@ public class PbapClientService extends ProfileService { + "=?"; String[] selectionArgs = new String[] {accountName, componentName.flattenToString()}; try { BluetoothMethodProxy.getInstance() .contentResolverDelete( getContentResolver(), CallLog.Calls.CONTENT_URI, selectionFilter, selectionArgs); getContentResolver().delete(CallLog.Calls.CONTENT_URI, selectionFilter, selectionArgs); } catch (IllegalArgumentException e) { Log.w(TAG, "Call Logs could not be deleted, they may not exist yet."); } Loading Loading @@ -345,7 +338,7 @@ public class PbapClientService extends ProfileService { Log.d(TAG, "Received intent to disconnect HFP with " + device); // HFP client stores entries in calllog.db by BD_ADDR and component name // Using the current Service as the context. removeHfpCallLog(device.getAddress(), this); removeHfpCallLog(device.getAddress()); } } Loading android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientServiceTest.java +149 −86 Original line number Diff line number Diff line Loading @@ -19,6 +19,8 @@ import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertThrows; import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.anyString; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.mock; Loading @@ -27,19 +29,26 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.accounts.Account; import android.accounts.AccountManager; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothProfile; import android.content.ContentResolver; import android.content.ContentValues; import android.content.Context; import android.content.pm.PackageManager; import android.content.res.Resources; import android.content.Intent; import android.net.Uri; import android.os.Looper; import android.provider.CallLog; import android.test.mock.MockContentProvider; import android.test.mock.MockContentResolver; import androidx.test.InstrumentationRegistry; import androidx.test.filters.MediumTest; import androidx.test.runner.AndroidJUnit4; import com.android.bluetooth.BluetoothMethodProxy; import com.android.bluetooth.TestUtils; import com.android.bluetooth.btservice.AdapterService; import com.android.bluetooth.btservice.storage.DatabaseManager; Loading @@ -62,47 +71,72 @@ public class PbapClientServiceTest { private PbapClientService mService = null; private BluetoothAdapter mAdapter = null; private Context mTargetContext; private BluetoothDevice mRemoteDevice; boolean mIsAdapterServiceSet; boolean mIsPbapClientServiceStarted; @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); @Mock private AdapterService mAdapterService; @Mock private Context mMockContext; @Mock private AdapterService mMockAdapterService; @Mock private DatabaseManager mDatabaseManager; @Mock private PackageManager mMockPackageManager; private MockContentResolver mMockContentResolver; private MockCallLogProvider mMockCallLogProvider; @Mock private Resources mMockResources; @Mock private AccountManager mMockAccountManager; @Before public void setUp() throws Exception { mTargetContext = InstrumentationRegistry.getTargetContext(); TestUtils.setAdapterService(mAdapterService); mIsAdapterServiceSet = true; doReturn(mDatabaseManager).when(mAdapterService).getDatabase(); mService = new PbapClientService(mTargetContext); mService.start(); mService.setAvailable(true); mIsPbapClientServiceStarted = true; // Try getting the Bluetooth adapter TestUtils.setAdapterService(mMockAdapterService); doReturn(mDatabaseManager).when(mMockAdapterService).getDatabase(); doReturn("").when(mMockContext).getPackageName(); doReturn(mMockPackageManager).when(mMockContext).getPackageManager(); doReturn(mMockResources).when(mMockContext).getResources(); doReturn(Utils.ACCOUNT_TYPE).when(mMockResources).getString(anyInt()); mMockContentResolver = new MockContentResolver(); mMockCallLogProvider = new MockCallLogProvider(); mMockContentResolver.addProvider(CallLog.AUTHORITY, mMockCallLogProvider); doReturn(mMockContentResolver).when(mMockContext).getContentResolver(); doReturn(AccountManager.VISIBILITY_VISIBLE) .when(mMockAccountManager) .getAccountVisibility(any(Account.class), anyString()); doReturn(new Account[]{}) .when(mMockAccountManager) .getAccountsByType(eq(Utils.ACCOUNT_TYPE)); TestUtils.mockGetSystemService( mMockContext, Context.ACCOUNT_SERVICE, AccountManager.class, mMockAccountManager); mAdapter = BluetoothAdapter.getDefaultAdapter(); Assert.assertNotNull(mAdapter); mRemoteDevice = mAdapter.getRemoteDevice(REMOTE_DEVICE_ADDRESS); if (Looper.myLooper() == null) { Looper.prepare(); } mService = new PbapClientService(mMockContext); mService.start(); mService.setAvailable(true); } @After public void tearDown() throws Exception { if (!mIsAdapterServiceSet) { return; } if (mIsPbapClientServiceStarted) { if (mService != null) { mService.stop(); mService = PbapClientService.getPbapClientService(); Assert.assertNull(mService); mService = null; } TestUtils.clearAdapterService(mAdapterService); BluetoothMethodProxy.setInstanceForTesting(null); TestUtils.clearAdapterService(mMockAdapterService); } // ********************************************************************************************* // * Initialize Service // ********************************************************************************************* @Test public void testInitialize() { Assert.assertNotNull(PbapClientService.getPbapClientService()); Loading @@ -115,17 +149,81 @@ public class PbapClientServiceTest { assertThat(PbapClientService.getPbapClientService()).isNull(); } // ********************************************************************************************* // * Incoming Events // ********************************************************************************************* // ACL state changes from AdapterService @Test public void dump_callsStateMachineDump() { public void aclDisconnected_withLeTransport_doesNotCallDisconnect() { int connectionState = BluetoothProfile.STATE_CONNECTED; PbapClientStateMachine sm = mock(PbapClientStateMachine.class); mService.mPbapClientStateMachineMap.put(mRemoteDevice, sm); StringBuilder builder = new StringBuilder(); when(sm.getConnectionState(mRemoteDevice)).thenReturn(connectionState); mService.dump(builder); mService.aclDisconnected(mRemoteDevice, BluetoothDevice.TRANSPORT_LE); TestUtils.waitForLooperToFinishScheduledTask(Looper.getMainLooper()); verify(sm).dump(builder); verify(sm, never()).disconnect(mRemoteDevice); } @Test public void aclDisconnected_withBrEdrTransport_callsDisconnect() { int connectionState = BluetoothProfile.STATE_CONNECTED; PbapClientStateMachine sm = mock(PbapClientStateMachine.class); mService.mPbapClientStateMachineMap.put(mRemoteDevice, sm); when(sm.getConnectionState(mRemoteDevice)).thenReturn(connectionState); mService.aclDisconnected(mRemoteDevice, BluetoothDevice.TRANSPORT_BREDR); TestUtils.waitForLooperToFinishScheduledTask(Looper.getMainLooper()); verify(sm).disconnect(mRemoteDevice); } // User unlock state changes @Test public void broadcastReceiver_withActionUserUnlocked_callsTryDownloadIfConnected() { PbapClientStateMachine sm = mock(PbapClientStateMachine.class); mService.mPbapClientStateMachineMap.put(mRemoteDevice, sm); Intent intent = new Intent(Intent.ACTION_USER_UNLOCKED); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mRemoteDevice); mService.mPbapBroadcastReceiver.onReceive(mService, intent); verify(sm).tryDownloadIfConnected(); } // HFP HF State changes @Test public void headsetClientConnectionStateChanged_hfpCallLogIsRemoved() { mService.handleHeadsetClientConnectionStateChanged( mRemoteDevice, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED); assertThat(mMockCallLogProvider.getMostRecentlyDeletedDevice()) .isEqualTo(mRemoteDevice.getAddress()); } // Device state machines cleans up @Test public void cleanUpDevice() { PbapClientStateMachine sm = mock(PbapClientStateMachine.class); mService.mPbapClientStateMachineMap.put(mRemoteDevice, sm); mService.cleanupDevice(mRemoteDevice); assertThat(mService.mPbapClientStateMachineMap).doesNotContainKey(mRemoteDevice); } // ********************************************************************************************* // * API Methods // ********************************************************************************************* @Test public void testSetConnectionPolicy_withNullDevice_throwsIAE() { assertThrows( Loading Loading @@ -211,73 +309,38 @@ public class PbapClientServiceTest { .isEqualTo(BluetoothProfile.STATE_DISCONNECTED); } @Test public void cleanUpDevice() { PbapClientStateMachine sm = mock(PbapClientStateMachine.class); mService.mPbapClientStateMachineMap.put(mRemoteDevice, sm); mService.cleanupDevice(mRemoteDevice); assertThat(mService.mPbapClientStateMachineMap).doesNotContainKey(mRemoteDevice); } // ********************************************************************************************* // * Debug/Dump/toString() // ********************************************************************************************* @Test public void broadcastReceiver_withActionAclDisconnectedLeTransport_doesNotCallDisconnect() { int connectionState = BluetoothProfile.STATE_CONNECTED; public void dump_callsStateMachineDump() { PbapClientStateMachine sm = mock(PbapClientStateMachine.class); mService.mPbapClientStateMachineMap.put(mRemoteDevice, sm); when(sm.getConnectionState(mRemoteDevice)).thenReturn(connectionState); StringBuilder builder = new StringBuilder(); mService.aclDisconnected(mRemoteDevice, BluetoothDevice.TRANSPORT_LE); TestUtils.waitForLooperToFinishScheduledTask(Looper.getMainLooper()); mService.dump(builder); verify(sm, never()).disconnect(mRemoteDevice); verify(sm).dump(builder); } @Test public void broadcastReceiver_withActionAclDisconnectedBrEdrTransport_callsDisconnect() { int connectionState = BluetoothProfile.STATE_CONNECTED; PbapClientStateMachine sm = mock(PbapClientStateMachine.class); mService.mPbapClientStateMachineMap.put(mRemoteDevice, sm); when(sm.getConnectionState(mRemoteDevice)).thenReturn(connectionState); // ********************************************************************************************* // * Fake Call Log Provider // ********************************************************************************************* mService.aclDisconnected(mRemoteDevice, BluetoothDevice.TRANSPORT_BREDR); TestUtils.waitForLooperToFinishScheduledTask(Looper.getMainLooper()); private static class MockCallLogProvider extends MockContentProvider { private String mMostRecentlyDeletedDevice = null; verify(sm).disconnect(mRemoteDevice); @Override public int delete(Uri uri, String selection, String[] selectionArgs) { if (selectionArgs != null && selectionArgs.length > 0) { mMostRecentlyDeletedDevice = selectionArgs[0]; } @Test public void broadcastReceiver_withActionUserUnlocked_callsTryDownloadIfConnected() { PbapClientStateMachine sm = mock(PbapClientStateMachine.class); mService.mPbapClientStateMachineMap.put(mRemoteDevice, sm); Intent intent = new Intent(Intent.ACTION_USER_UNLOCKED); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mRemoteDevice); mService.mPbapBroadcastReceiver.onReceive(mService, intent); verify(sm).tryDownloadIfConnected(); return 0; } @Test public void headsetClientConnectionStateChanged_hfpCallLogIsRemoved() { BluetoothMethodProxy methodProxy = spy(BluetoothMethodProxy.getInstance()); BluetoothMethodProxy.setInstanceForTesting(methodProxy); mService.handleHeadsetClientConnectionStateChanged( mRemoteDevice, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED); ArgumentCaptor<Object> selectionArgsCaptor = ArgumentCaptor.forClass(Object.class); verify(methodProxy) .contentResolverDelete( any(), eq(CallLog.Calls.CONTENT_URI), any(), (String[]) selectionArgsCaptor.capture()); assertThat(((String[]) selectionArgsCaptor.getValue())[0]) .isEqualTo(mRemoteDevice.getAddress()); public String getMostRecentlyDeletedDevice() { return mMostRecentlyDeletedDevice; } } } android/app/tests/unit/src/com/android/bluetooth/pbapclient/Utils.java +3 −0 Original line number Diff line number Diff line Loading @@ -38,6 +38,9 @@ public class Utils { public static final String OUTGOING_CALL = "DIALED"; private static final String CALL_HISTORY = "X-IRMC-CALL-DATETIME"; public static final String ACCOUNT_TYPE = "com.android.bluetooth.pbapclient"; /** * Group a list of VCard entries or Call History entries into a full phonebook * Loading Loading
android/app/src/com/android/bluetooth/pbapclient/PbapClientService.java +5 −12 Original line number Diff line number Diff line Loading @@ -35,7 +35,6 @@ import android.provider.CallLog; import android.sysprop.BluetoothProperties; import android.util.Log; import com.android.bluetooth.BluetoothMethodProxy; import com.android.bluetooth.R; import com.android.bluetooth.btservice.AdapterService; import com.android.bluetooth.btservice.ProfileService; Loading Loading @@ -297,11 +296,10 @@ public class PbapClientService extends ProfileService { } } private void removeHfpCallLog(String accountName, Context context) { private void removeHfpCallLog(String accountName) { Log.d(TAG, "Removing call logs from " + accountName); // Delete call logs belonging to accountName==BD_ADDR that also match // component name "hfpclient". ComponentName componentName = new ComponentName(context, HfpClientConnectionService.class); // Delete call logs belonging to accountName==BD_ADDR that also match component "hfpclient" ComponentName componentName = new ComponentName(this, HfpClientConnectionService.class); String selectionFilter = CallLog.Calls.PHONE_ACCOUNT_ID + "=? AND " Loading @@ -309,12 +307,7 @@ public class PbapClientService extends ProfileService { + "=?"; String[] selectionArgs = new String[] {accountName, componentName.flattenToString()}; try { BluetoothMethodProxy.getInstance() .contentResolverDelete( getContentResolver(), CallLog.Calls.CONTENT_URI, selectionFilter, selectionArgs); getContentResolver().delete(CallLog.Calls.CONTENT_URI, selectionFilter, selectionArgs); } catch (IllegalArgumentException e) { Log.w(TAG, "Call Logs could not be deleted, they may not exist yet."); } Loading Loading @@ -345,7 +338,7 @@ public class PbapClientService extends ProfileService { Log.d(TAG, "Received intent to disconnect HFP with " + device); // HFP client stores entries in calllog.db by BD_ADDR and component name // Using the current Service as the context. removeHfpCallLog(device.getAddress(), this); removeHfpCallLog(device.getAddress()); } } Loading
android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientServiceTest.java +149 −86 Original line number Diff line number Diff line Loading @@ -19,6 +19,8 @@ import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertThrows; import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.anyString; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.mock; Loading @@ -27,19 +29,26 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.accounts.Account; import android.accounts.AccountManager; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothProfile; import android.content.ContentResolver; import android.content.ContentValues; import android.content.Context; import android.content.pm.PackageManager; import android.content.res.Resources; import android.content.Intent; import android.net.Uri; import android.os.Looper; import android.provider.CallLog; import android.test.mock.MockContentProvider; import android.test.mock.MockContentResolver; import androidx.test.InstrumentationRegistry; import androidx.test.filters.MediumTest; import androidx.test.runner.AndroidJUnit4; import com.android.bluetooth.BluetoothMethodProxy; import com.android.bluetooth.TestUtils; import com.android.bluetooth.btservice.AdapterService; import com.android.bluetooth.btservice.storage.DatabaseManager; Loading @@ -62,47 +71,72 @@ public class PbapClientServiceTest { private PbapClientService mService = null; private BluetoothAdapter mAdapter = null; private Context mTargetContext; private BluetoothDevice mRemoteDevice; boolean mIsAdapterServiceSet; boolean mIsPbapClientServiceStarted; @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); @Mock private AdapterService mAdapterService; @Mock private Context mMockContext; @Mock private AdapterService mMockAdapterService; @Mock private DatabaseManager mDatabaseManager; @Mock private PackageManager mMockPackageManager; private MockContentResolver mMockContentResolver; private MockCallLogProvider mMockCallLogProvider; @Mock private Resources mMockResources; @Mock private AccountManager mMockAccountManager; @Before public void setUp() throws Exception { mTargetContext = InstrumentationRegistry.getTargetContext(); TestUtils.setAdapterService(mAdapterService); mIsAdapterServiceSet = true; doReturn(mDatabaseManager).when(mAdapterService).getDatabase(); mService = new PbapClientService(mTargetContext); mService.start(); mService.setAvailable(true); mIsPbapClientServiceStarted = true; // Try getting the Bluetooth adapter TestUtils.setAdapterService(mMockAdapterService); doReturn(mDatabaseManager).when(mMockAdapterService).getDatabase(); doReturn("").when(mMockContext).getPackageName(); doReturn(mMockPackageManager).when(mMockContext).getPackageManager(); doReturn(mMockResources).when(mMockContext).getResources(); doReturn(Utils.ACCOUNT_TYPE).when(mMockResources).getString(anyInt()); mMockContentResolver = new MockContentResolver(); mMockCallLogProvider = new MockCallLogProvider(); mMockContentResolver.addProvider(CallLog.AUTHORITY, mMockCallLogProvider); doReturn(mMockContentResolver).when(mMockContext).getContentResolver(); doReturn(AccountManager.VISIBILITY_VISIBLE) .when(mMockAccountManager) .getAccountVisibility(any(Account.class), anyString()); doReturn(new Account[]{}) .when(mMockAccountManager) .getAccountsByType(eq(Utils.ACCOUNT_TYPE)); TestUtils.mockGetSystemService( mMockContext, Context.ACCOUNT_SERVICE, AccountManager.class, mMockAccountManager); mAdapter = BluetoothAdapter.getDefaultAdapter(); Assert.assertNotNull(mAdapter); mRemoteDevice = mAdapter.getRemoteDevice(REMOTE_DEVICE_ADDRESS); if (Looper.myLooper() == null) { Looper.prepare(); } mService = new PbapClientService(mMockContext); mService.start(); mService.setAvailable(true); } @After public void tearDown() throws Exception { if (!mIsAdapterServiceSet) { return; } if (mIsPbapClientServiceStarted) { if (mService != null) { mService.stop(); mService = PbapClientService.getPbapClientService(); Assert.assertNull(mService); mService = null; } TestUtils.clearAdapterService(mAdapterService); BluetoothMethodProxy.setInstanceForTesting(null); TestUtils.clearAdapterService(mMockAdapterService); } // ********************************************************************************************* // * Initialize Service // ********************************************************************************************* @Test public void testInitialize() { Assert.assertNotNull(PbapClientService.getPbapClientService()); Loading @@ -115,17 +149,81 @@ public class PbapClientServiceTest { assertThat(PbapClientService.getPbapClientService()).isNull(); } // ********************************************************************************************* // * Incoming Events // ********************************************************************************************* // ACL state changes from AdapterService @Test public void dump_callsStateMachineDump() { public void aclDisconnected_withLeTransport_doesNotCallDisconnect() { int connectionState = BluetoothProfile.STATE_CONNECTED; PbapClientStateMachine sm = mock(PbapClientStateMachine.class); mService.mPbapClientStateMachineMap.put(mRemoteDevice, sm); StringBuilder builder = new StringBuilder(); when(sm.getConnectionState(mRemoteDevice)).thenReturn(connectionState); mService.dump(builder); mService.aclDisconnected(mRemoteDevice, BluetoothDevice.TRANSPORT_LE); TestUtils.waitForLooperToFinishScheduledTask(Looper.getMainLooper()); verify(sm).dump(builder); verify(sm, never()).disconnect(mRemoteDevice); } @Test public void aclDisconnected_withBrEdrTransport_callsDisconnect() { int connectionState = BluetoothProfile.STATE_CONNECTED; PbapClientStateMachine sm = mock(PbapClientStateMachine.class); mService.mPbapClientStateMachineMap.put(mRemoteDevice, sm); when(sm.getConnectionState(mRemoteDevice)).thenReturn(connectionState); mService.aclDisconnected(mRemoteDevice, BluetoothDevice.TRANSPORT_BREDR); TestUtils.waitForLooperToFinishScheduledTask(Looper.getMainLooper()); verify(sm).disconnect(mRemoteDevice); } // User unlock state changes @Test public void broadcastReceiver_withActionUserUnlocked_callsTryDownloadIfConnected() { PbapClientStateMachine sm = mock(PbapClientStateMachine.class); mService.mPbapClientStateMachineMap.put(mRemoteDevice, sm); Intent intent = new Intent(Intent.ACTION_USER_UNLOCKED); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mRemoteDevice); mService.mPbapBroadcastReceiver.onReceive(mService, intent); verify(sm).tryDownloadIfConnected(); } // HFP HF State changes @Test public void headsetClientConnectionStateChanged_hfpCallLogIsRemoved() { mService.handleHeadsetClientConnectionStateChanged( mRemoteDevice, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED); assertThat(mMockCallLogProvider.getMostRecentlyDeletedDevice()) .isEqualTo(mRemoteDevice.getAddress()); } // Device state machines cleans up @Test public void cleanUpDevice() { PbapClientStateMachine sm = mock(PbapClientStateMachine.class); mService.mPbapClientStateMachineMap.put(mRemoteDevice, sm); mService.cleanupDevice(mRemoteDevice); assertThat(mService.mPbapClientStateMachineMap).doesNotContainKey(mRemoteDevice); } // ********************************************************************************************* // * API Methods // ********************************************************************************************* @Test public void testSetConnectionPolicy_withNullDevice_throwsIAE() { assertThrows( Loading Loading @@ -211,73 +309,38 @@ public class PbapClientServiceTest { .isEqualTo(BluetoothProfile.STATE_DISCONNECTED); } @Test public void cleanUpDevice() { PbapClientStateMachine sm = mock(PbapClientStateMachine.class); mService.mPbapClientStateMachineMap.put(mRemoteDevice, sm); mService.cleanupDevice(mRemoteDevice); assertThat(mService.mPbapClientStateMachineMap).doesNotContainKey(mRemoteDevice); } // ********************************************************************************************* // * Debug/Dump/toString() // ********************************************************************************************* @Test public void broadcastReceiver_withActionAclDisconnectedLeTransport_doesNotCallDisconnect() { int connectionState = BluetoothProfile.STATE_CONNECTED; public void dump_callsStateMachineDump() { PbapClientStateMachine sm = mock(PbapClientStateMachine.class); mService.mPbapClientStateMachineMap.put(mRemoteDevice, sm); when(sm.getConnectionState(mRemoteDevice)).thenReturn(connectionState); StringBuilder builder = new StringBuilder(); mService.aclDisconnected(mRemoteDevice, BluetoothDevice.TRANSPORT_LE); TestUtils.waitForLooperToFinishScheduledTask(Looper.getMainLooper()); mService.dump(builder); verify(sm, never()).disconnect(mRemoteDevice); verify(sm).dump(builder); } @Test public void broadcastReceiver_withActionAclDisconnectedBrEdrTransport_callsDisconnect() { int connectionState = BluetoothProfile.STATE_CONNECTED; PbapClientStateMachine sm = mock(PbapClientStateMachine.class); mService.mPbapClientStateMachineMap.put(mRemoteDevice, sm); when(sm.getConnectionState(mRemoteDevice)).thenReturn(connectionState); // ********************************************************************************************* // * Fake Call Log Provider // ********************************************************************************************* mService.aclDisconnected(mRemoteDevice, BluetoothDevice.TRANSPORT_BREDR); TestUtils.waitForLooperToFinishScheduledTask(Looper.getMainLooper()); private static class MockCallLogProvider extends MockContentProvider { private String mMostRecentlyDeletedDevice = null; verify(sm).disconnect(mRemoteDevice); @Override public int delete(Uri uri, String selection, String[] selectionArgs) { if (selectionArgs != null && selectionArgs.length > 0) { mMostRecentlyDeletedDevice = selectionArgs[0]; } @Test public void broadcastReceiver_withActionUserUnlocked_callsTryDownloadIfConnected() { PbapClientStateMachine sm = mock(PbapClientStateMachine.class); mService.mPbapClientStateMachineMap.put(mRemoteDevice, sm); Intent intent = new Intent(Intent.ACTION_USER_UNLOCKED); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mRemoteDevice); mService.mPbapBroadcastReceiver.onReceive(mService, intent); verify(sm).tryDownloadIfConnected(); return 0; } @Test public void headsetClientConnectionStateChanged_hfpCallLogIsRemoved() { BluetoothMethodProxy methodProxy = spy(BluetoothMethodProxy.getInstance()); BluetoothMethodProxy.setInstanceForTesting(methodProxy); mService.handleHeadsetClientConnectionStateChanged( mRemoteDevice, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED); ArgumentCaptor<Object> selectionArgsCaptor = ArgumentCaptor.forClass(Object.class); verify(methodProxy) .contentResolverDelete( any(), eq(CallLog.Calls.CONTENT_URI), any(), (String[]) selectionArgsCaptor.capture()); assertThat(((String[]) selectionArgsCaptor.getValue())[0]) .isEqualTo(mRemoteDevice.getAddress()); public String getMostRecentlyDeletedDevice() { return mMostRecentlyDeletedDevice; } } }
android/app/tests/unit/src/com/android/bluetooth/pbapclient/Utils.java +3 −0 Original line number Diff line number Diff line Loading @@ -38,6 +38,9 @@ public class Utils { public static final String OUTGOING_CALL = "DIALED"; private static final String CALL_HISTORY = "X-IRMC-CALL-DATETIME"; public static final String ACCOUNT_TYPE = "com.android.bluetooth.pbapclient"; /** * Group a list of VCard entries or Call History entries into a full phonebook * Loading