Loading android/app/src/com/android/bluetooth/mapclient/MapClientService.java +13 −4 Original line number Diff line number Diff line Loading @@ -66,6 +66,8 @@ public class MapClientService extends ProfileService { @VisibleForTesting private Handler mHandler; @VisibleForTesting Looper mSmLooper; public static boolean isEnabled() { return BluetoothProperties.isProfileMapClientEnabled().orElse(false); } Loading Loading @@ -169,7 +171,9 @@ public class MapClientService extends ProfileService { private synchronized void addDeviceToMapAndConnect(BluetoothDevice device) { // When creating a new statemachine, its state is set to CONNECTING - which will trigger // connect. MceStateMachine mapStateMachine = new MceStateMachine(this, device); MceStateMachine mapStateMachine; if (mSmLooper != null) mapStateMachine = new MceStateMachine(this, device, mSmLooper); else mapStateMachine = new MceStateMachine(this, device); mMapInstanceMap.put(device, mapStateMachine); } Loading Loading @@ -367,9 +371,10 @@ public class MapClientService extends ProfileService { * cleanupDevice removes the associated state machine from the instance map * * @param device BluetoothDevice address of remote device * @param sm the state machine to clean up or {@code null} to clean up any state machine. */ @VisibleForTesting public void cleanupDevice(BluetoothDevice device) { public void cleanupDevice(BluetoothDevice device, MceStateMachine sm) { if (DBG) { StringBuilder sb = new StringBuilder(); dump(sb); Loading @@ -379,8 +384,12 @@ public class MapClientService extends ProfileService { synchronized (mMapInstanceMap) { MceStateMachine stateMachine = mMapInstanceMap.get(device); if (stateMachine != null) { if (sm == null || stateMachine == sm) { mMapInstanceMap.remove(device); stateMachine.doQuit(); } else { Log.w(TAG, "Trying to clean up wrong state machine"); } } } if (DBG) { Loading android/app/src/com/android/bluetooth/mapclient/MceStateMachine.java +25 −2 Original line number Diff line number Diff line Loading @@ -53,6 +53,7 @@ import android.bluetooth.BluetoothUuid; import android.bluetooth.SdpMasRecord; import android.content.Intent; import android.net.Uri; import android.os.Looper; import android.os.Message; import android.os.SystemProperties; import android.provider.Telephony; Loading Loading @@ -219,17 +220,39 @@ class MceStateMachine extends StateMachine { this(service, device, null, null); } MceStateMachine(MapClientService service, BluetoothDevice device, Looper looper) { this(service, device, null, null, looper); } @VisibleForTesting MceStateMachine(MapClientService service, BluetoothDevice device, MasClient masClient, MapClientContent database) { super(TAG); mService = service; mMasClient = masClient; mDevice = device; mDatabase = database; initStateMachine(); } @VisibleForTesting MceStateMachine( MapClientService service, BluetoothDevice device, MasClient masClient, MapClientContent database, Looper looper) { super(TAG, looper); mService = service; mMasClient = masClient; mDevice = device; mDatabase = database; initStateMachine(); } private void initStateMachine() { mPreviousState = BluetoothProfile.STATE_DISCONNECTED; mDevice = device; mDisconnected = new Disconnected(); mConnecting = new Connecting(); mDisconnecting = new Disconnecting(); Loading @@ -250,7 +273,7 @@ class MceStateMachine extends StateMachine { @Override protected void onQuitting() { if (mService != null) { mService.cleanupDevice(mDevice); mService.cleanupDevice(mDevice, this); } } Loading android/app/tests/unit/src/com/android/bluetooth/mapclient/MapClientServiceTest.java +39 −1 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import android.bluetooth.BluetoothProfile; import android.bluetooth.BluetoothUuid; import android.bluetooth.SdpMasRecord; import android.os.Looper; import android.os.test.TestLooper; import androidx.test.filters.MediumTest; import androidx.test.rule.ServiceTestRule; Loading Loading @@ -62,6 +63,7 @@ public class MapClientServiceTest { private MapClientService mService = null; private BluetoothAdapter mAdapter = null; private BluetoothDevice mRemoteDevice; private TestLooper mTestLooper; @Before public void setUp() throws Exception { Loading @@ -70,8 +72,13 @@ public class MapClientServiceTest { doReturn(mDatabaseManager).when(mAdapterService).getDatabase(); doReturn(true, false).when(mAdapterService).isStartedProfile(anyString()); TestUtils.startService(mServiceRule, MapClientService.class); mTestLooper = new TestLooper(); mService = MapClientService.getMapClientService(); assertThat(mService).isNotNull(); mService.mSmLooper = mTestLooper.getLooper(); // Try getting the Bluetooth adapter mAdapter = BluetoothAdapter.getDefaultAdapter(); assertThat(mAdapter).isNotNull(); Loading @@ -80,11 +87,13 @@ public class MapClientServiceTest { @After public void tearDown() throws Exception { mService.mSmLooper = null; TestUtils.stopService(mServiceRule, MapClientService.class); mService = MapClientService.getMapClientService(); assertThat(mService).isNull(); TestUtils.clearAdapterService(mAdapterService); BluetoothMethodProxy.setInstanceForTesting(null); mTestLooper.dispatchAll(); } @Test Loading Loading @@ -237,11 +246,39 @@ public class MapClientServiceTest { MceStateMachine sm = mock(MceStateMachine.class); mService.getInstanceMap().put(mRemoteDevice, sm); mService.cleanupDevice(mRemoteDevice); mService.cleanupDevice(mRemoteDevice, sm); assertThat(mService.getInstanceMap()).doesNotContainKey(mRemoteDevice); } @Test public void disconnect_doesNotCleanUpNewStateMachineOfSameDevice() { int connectionPolicy = BluetoothProfile.CONNECTION_POLICY_ALLOWED; when(mDatabaseManager.getProfileConnectionPolicy( mRemoteDevice, BluetoothProfile.MAP_CLIENT)) .thenReturn(connectionPolicy); mService.connect(mRemoteDevice); MceStateMachine connectedSm = mService.getInstanceMap().get(mRemoteDevice); assertThat(connectedSm).isNotNull(); connectedSm.sendMessage(MceStateMachine.MSG_MAS_SDP_DONE, mock(SdpMasRecord.class)); connectedSm.sendMessage(MceStateMachine.MSG_MAS_CONNECTED); // Stay it connected while (mTestLooper.isIdle() && connectedSm.getState() != BluetoothProfile.STATE_CONNECTED) { mTestLooper.dispatchNext(); } MceStateMachine sm = mock(MceStateMachine.class); mService.getInstanceMap().put(mRemoteDevice, sm); connectedSm.disconnect(); mTestLooper.dispatchAll(); assertThat(connectedSm.getState()).isEqualTo(BluetoothProfile.STATE_DISCONNECTED); assertThat(mService.getInstanceMap()).containsKey(mRemoteDevice); } @Test public void aclDisconnectedNoTransport_whenConnected_doesNotCallDisconnect() { int connectionState = BluetoothProfile.STATE_CONNECTED; Loading @@ -251,6 +288,7 @@ public class MapClientServiceTest { mService.aclDisconnected(mRemoteDevice, BluetoothDevice.ERROR); TestUtils.waitForLooperToBeIdle(Looper.getMainLooper()); mTestLooper.dispatchAll(); verify(sm, never()).disconnect(); } Loading android/app/tests/unit/src/com/android/bluetooth/mapclient/MapClientTest.java +1 −1 Original line number Diff line number Diff line Loading @@ -129,7 +129,7 @@ public class MapClientTest { TestUtils.waitForLooperToFinishScheduledTask(sm.getHandler().getLooper()); Assert.assertEquals(BluetoothProfile.STATE_CONNECTING, sm.getState()); mService.cleanupDevice(device); mService.cleanupDevice(device, sm); Assert.assertNull(mService.getInstanceMap().get(device)); } Loading Loading
android/app/src/com/android/bluetooth/mapclient/MapClientService.java +13 −4 Original line number Diff line number Diff line Loading @@ -66,6 +66,8 @@ public class MapClientService extends ProfileService { @VisibleForTesting private Handler mHandler; @VisibleForTesting Looper mSmLooper; public static boolean isEnabled() { return BluetoothProperties.isProfileMapClientEnabled().orElse(false); } Loading Loading @@ -169,7 +171,9 @@ public class MapClientService extends ProfileService { private synchronized void addDeviceToMapAndConnect(BluetoothDevice device) { // When creating a new statemachine, its state is set to CONNECTING - which will trigger // connect. MceStateMachine mapStateMachine = new MceStateMachine(this, device); MceStateMachine mapStateMachine; if (mSmLooper != null) mapStateMachine = new MceStateMachine(this, device, mSmLooper); else mapStateMachine = new MceStateMachine(this, device); mMapInstanceMap.put(device, mapStateMachine); } Loading Loading @@ -367,9 +371,10 @@ public class MapClientService extends ProfileService { * cleanupDevice removes the associated state machine from the instance map * * @param device BluetoothDevice address of remote device * @param sm the state machine to clean up or {@code null} to clean up any state machine. */ @VisibleForTesting public void cleanupDevice(BluetoothDevice device) { public void cleanupDevice(BluetoothDevice device, MceStateMachine sm) { if (DBG) { StringBuilder sb = new StringBuilder(); dump(sb); Loading @@ -379,8 +384,12 @@ public class MapClientService extends ProfileService { synchronized (mMapInstanceMap) { MceStateMachine stateMachine = mMapInstanceMap.get(device); if (stateMachine != null) { if (sm == null || stateMachine == sm) { mMapInstanceMap.remove(device); stateMachine.doQuit(); } else { Log.w(TAG, "Trying to clean up wrong state machine"); } } } if (DBG) { Loading
android/app/src/com/android/bluetooth/mapclient/MceStateMachine.java +25 −2 Original line number Diff line number Diff line Loading @@ -53,6 +53,7 @@ import android.bluetooth.BluetoothUuid; import android.bluetooth.SdpMasRecord; import android.content.Intent; import android.net.Uri; import android.os.Looper; import android.os.Message; import android.os.SystemProperties; import android.provider.Telephony; Loading Loading @@ -219,17 +220,39 @@ class MceStateMachine extends StateMachine { this(service, device, null, null); } MceStateMachine(MapClientService service, BluetoothDevice device, Looper looper) { this(service, device, null, null, looper); } @VisibleForTesting MceStateMachine(MapClientService service, BluetoothDevice device, MasClient masClient, MapClientContent database) { super(TAG); mService = service; mMasClient = masClient; mDevice = device; mDatabase = database; initStateMachine(); } @VisibleForTesting MceStateMachine( MapClientService service, BluetoothDevice device, MasClient masClient, MapClientContent database, Looper looper) { super(TAG, looper); mService = service; mMasClient = masClient; mDevice = device; mDatabase = database; initStateMachine(); } private void initStateMachine() { mPreviousState = BluetoothProfile.STATE_DISCONNECTED; mDevice = device; mDisconnected = new Disconnected(); mConnecting = new Connecting(); mDisconnecting = new Disconnecting(); Loading @@ -250,7 +273,7 @@ class MceStateMachine extends StateMachine { @Override protected void onQuitting() { if (mService != null) { mService.cleanupDevice(mDevice); mService.cleanupDevice(mDevice, this); } } Loading
android/app/tests/unit/src/com/android/bluetooth/mapclient/MapClientServiceTest.java +39 −1 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import android.bluetooth.BluetoothProfile; import android.bluetooth.BluetoothUuid; import android.bluetooth.SdpMasRecord; import android.os.Looper; import android.os.test.TestLooper; import androidx.test.filters.MediumTest; import androidx.test.rule.ServiceTestRule; Loading Loading @@ -62,6 +63,7 @@ public class MapClientServiceTest { private MapClientService mService = null; private BluetoothAdapter mAdapter = null; private BluetoothDevice mRemoteDevice; private TestLooper mTestLooper; @Before public void setUp() throws Exception { Loading @@ -70,8 +72,13 @@ public class MapClientServiceTest { doReturn(mDatabaseManager).when(mAdapterService).getDatabase(); doReturn(true, false).when(mAdapterService).isStartedProfile(anyString()); TestUtils.startService(mServiceRule, MapClientService.class); mTestLooper = new TestLooper(); mService = MapClientService.getMapClientService(); assertThat(mService).isNotNull(); mService.mSmLooper = mTestLooper.getLooper(); // Try getting the Bluetooth adapter mAdapter = BluetoothAdapter.getDefaultAdapter(); assertThat(mAdapter).isNotNull(); Loading @@ -80,11 +87,13 @@ public class MapClientServiceTest { @After public void tearDown() throws Exception { mService.mSmLooper = null; TestUtils.stopService(mServiceRule, MapClientService.class); mService = MapClientService.getMapClientService(); assertThat(mService).isNull(); TestUtils.clearAdapterService(mAdapterService); BluetoothMethodProxy.setInstanceForTesting(null); mTestLooper.dispatchAll(); } @Test Loading Loading @@ -237,11 +246,39 @@ public class MapClientServiceTest { MceStateMachine sm = mock(MceStateMachine.class); mService.getInstanceMap().put(mRemoteDevice, sm); mService.cleanupDevice(mRemoteDevice); mService.cleanupDevice(mRemoteDevice, sm); assertThat(mService.getInstanceMap()).doesNotContainKey(mRemoteDevice); } @Test public void disconnect_doesNotCleanUpNewStateMachineOfSameDevice() { int connectionPolicy = BluetoothProfile.CONNECTION_POLICY_ALLOWED; when(mDatabaseManager.getProfileConnectionPolicy( mRemoteDevice, BluetoothProfile.MAP_CLIENT)) .thenReturn(connectionPolicy); mService.connect(mRemoteDevice); MceStateMachine connectedSm = mService.getInstanceMap().get(mRemoteDevice); assertThat(connectedSm).isNotNull(); connectedSm.sendMessage(MceStateMachine.MSG_MAS_SDP_DONE, mock(SdpMasRecord.class)); connectedSm.sendMessage(MceStateMachine.MSG_MAS_CONNECTED); // Stay it connected while (mTestLooper.isIdle() && connectedSm.getState() != BluetoothProfile.STATE_CONNECTED) { mTestLooper.dispatchNext(); } MceStateMachine sm = mock(MceStateMachine.class); mService.getInstanceMap().put(mRemoteDevice, sm); connectedSm.disconnect(); mTestLooper.dispatchAll(); assertThat(connectedSm.getState()).isEqualTo(BluetoothProfile.STATE_DISCONNECTED); assertThat(mService.getInstanceMap()).containsKey(mRemoteDevice); } @Test public void aclDisconnectedNoTransport_whenConnected_doesNotCallDisconnect() { int connectionState = BluetoothProfile.STATE_CONNECTED; Loading @@ -251,6 +288,7 @@ public class MapClientServiceTest { mService.aclDisconnected(mRemoteDevice, BluetoothDevice.ERROR); TestUtils.waitForLooperToBeIdle(Looper.getMainLooper()); mTestLooper.dispatchAll(); verify(sm, never()).disconnect(); } Loading
android/app/tests/unit/src/com/android/bluetooth/mapclient/MapClientTest.java +1 −1 Original line number Diff line number Diff line Loading @@ -129,7 +129,7 @@ public class MapClientTest { TestUtils.waitForLooperToFinishScheduledTask(sm.getHandler().getLooper()); Assert.assertEquals(BluetoothProfile.STATE_CONNECTING, sm.getState()); mService.cleanupDevice(device); mService.cleanupDevice(device, sm); Assert.assertNull(mService.getInstanceMap().get(device)); } Loading