Loading android/app/src/com/android/bluetooth/hap/HapClientService.java +5 −0 Original line number Diff line number Diff line Loading @@ -1209,6 +1209,8 @@ public class HapClientService extends ProfileService { @VisibleForTesting static class BluetoothHapClientBinder extends IBluetoothHapClient.Stub implements IProfileServiceBinder { @VisibleForTesting boolean mIsTesting = false; private HapClientService mService; BluetoothHapClientBinder(HapClientService svc) { Loading @@ -1216,6 +1218,9 @@ public class HapClientService extends ProfileService { } private HapClientService getService(AttributionSource source) { if (mIsTesting) { return mService; } if (!Utils.checkCallerIsSystemOrActiveUser(TAG) || !Utils.checkServiceAvailable(mService, TAG) || !Utils.checkConnectPermissionForDataDelivery(mService, source, TAG)) { Loading android/app/tests/unit/src/com/android/bluetooth/hap/HapClientTest.java +149 −34 Original line number Diff line number Diff line Loading @@ -17,9 +17,26 @@ package com.android.bluetooth.hap; import static org.mockito.Mockito.*; import android.bluetooth.*; import static org.mockito.Mockito.after; import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.anyString; import static org.mockito.Mockito.doCallRealMethod; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothHapClient; import android.bluetooth.BluetoothHapPresetInfo; import android.bluetooth.BluetoothProfile; import android.bluetooth.BluetoothStatusCodes; import android.bluetooth.BluetoothUuid; import android.bluetooth.IBluetoothHapClientCallback; import android.content.AttributionSource; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; Loading @@ -28,32 +45,32 @@ import android.os.Binder; import android.os.Looper; import android.os.ParcelUuid; import android.os.RemoteException; import android.util.Log; import androidx.test.InstrumentationRegistry; import androidx.test.filters.MediumTest; import androidx.test.rule.ServiceTestRule; import androidx.test.runner.AndroidJUnit4; import com.android.bluetooth.R; import com.android.bluetooth.TestUtils; import com.android.bluetooth.Utils; import com.android.bluetooth.btservice.AdapterService; import com.android.bluetooth.btservice.ServiceFactory; import com.android.bluetooth.btservice.storage.DatabaseManager; import com.android.bluetooth.csip.CsipSetCoordinatorService; import com.android.bluetooth.x.com.android.modules.utils.SynchronousResultReceiver; import org.junit.After; import org.junit.Assert; import org.junit.Assume; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import java.time.Duration; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; Loading @@ -77,6 +94,8 @@ public class HapClientTest { private BluetoothDevice mDevice3; private Context mTargetContext; private HapClientService mService; private HapClientService.BluetoothHapClientBinder mServiceBinder; private AttributionSource mAttributionSource; private HasIntentReceiver mHasIntentReceiver; private HashMap<BluetoothDevice, LinkedBlockingQueue<Intent>> mIntentQueue; Loading Loading @@ -116,11 +135,14 @@ public class HapClientTest { doReturn(true, false).when(mAdapterService).isStartedProfile(anyString()); mAdapter = BluetoothAdapter.getDefaultAdapter(); mAttributionSource = mAdapter.getAttributionSource(); startService(); mService.mHapClientNativeInterface = mNativeInterface; mService.mFactory = mServiceFactory; doReturn(mCsipService).when(mServiceFactory).getCsipSetCoordinatorService(); mServiceBinder = (HapClientService.BluetoothHapClientBinder) mService.initBinder(); mServiceBinder.mIsTesting = true; // Set up the State Changed receiver IntentFilter filter = new IntentFilter(); Loading Loading @@ -260,7 +282,7 @@ public class HapClientTest { * Test get/set policy for BluetoothDevice */ @Test public void testGetSetPolicy() { public void testGetSetPolicy() throws Exception { when(mDatabaseManager .getProfileConnectionPolicy(mDevice, BluetoothProfile.HAP_CLIENT)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_UNKNOWN); Loading @@ -278,9 +300,14 @@ public class HapClientTest { when(mDatabaseManager .getProfileConnectionPolicy(mDevice, BluetoothProfile.HAP_CLIENT)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); // call getConnectionPolicy via binder final SynchronousResultReceiver<Integer> recv = SynchronousResultReceiver.get(); int defaultRecvValue = -1000; mServiceBinder.getConnectionPolicy(mDevice, mAttributionSource, recv); int policy = recv.awaitResultNoInterrupt(Duration.ofMillis(TIMEOUT_MS)) .getValue(defaultRecvValue); Assert.assertEquals("Setting device policy to POLICY_ALLOWED", BluetoothProfile.CONNECTION_POLICY_ALLOWED, mService.getConnectionPolicy(mDevice)); BluetoothProfile.CONNECTION_POLICY_ALLOWED, policy); } /** Loading Loading @@ -398,7 +425,7 @@ public class HapClientTest { * Test that an outgoing connection times out */ @Test public void testOutgoingConnectTimeout() { public void testOutgoingConnectTimeout() throws Exception { // Update the device policy so okToConnect() returns true when(mDatabaseManager .getProfileConnectionPolicy(mDevice, BluetoothProfile.HAP_CLIENT)) Loading @@ -415,19 +442,22 @@ public class HapClientTest { Assert.assertEquals(BluetoothProfile.STATE_CONNECTING, mService.getConnectionState(mDevice)); // Verify the connection state broadcast, and that we are in Disconnected state // Verify the connection state broadcast, and that we are in Disconnected state via binder verifyConnectionStateIntent(HapClientStateMachine.sConnectTimeoutMs * 2, mDevice, BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_CONNECTING); Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTED, mService.getConnectionState(mDevice)); mDevice, BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_CONNECTING); final SynchronousResultReceiver<Integer> recv = SynchronousResultReceiver.get(); int defaultRecvValue = -1000; mServiceBinder.getConnectionState(mDevice, mAttributionSource, recv); int state = recv.awaitResultNoInterrupt(Duration.ofMillis(TIMEOUT_MS)) .getValue(defaultRecvValue); Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTED, state); } /** * Test that an outgoing connection to two device that have HAS UUID is successful */ @Test public void testConnectTwo() { public void testConnectTwo() throws Exception { doReturn(new ParcelUuid[]{BluetoothUuid.HAS}).when(mAdapterService) .getRemoteUuids(any(BluetoothDevice.class)); Loading @@ -438,7 +468,12 @@ public class HapClientTest { BluetoothDevice Device2 = TestUtils.getTestDevice(mAdapter, 1); testConnectingDevice(Device2); List<BluetoothDevice> devices = mService.getConnectedDevices(); // indirect call of mService.getConnectedDevices to test BluetoothHearingAidBinder final SynchronousResultReceiver<List<BluetoothDevice>> recv = SynchronousResultReceiver.get(); mServiceBinder.getConnectedDevices(mAttributionSource, recv); List<BluetoothDevice> devices = recv.awaitResultNoInterrupt(Duration.ofMillis(TIMEOUT_MS)) .getValue(null); Assert.assertTrue(devices.contains(mDevice)); Assert.assertTrue(devices.contains(Device2)); Assert.assertNotEquals(mDevice, Device2); Loading @@ -457,7 +492,7 @@ public class HapClientTest { * Test getting HAS coordinated sets. */ @Test public void testGetHapGroupCoordinatedOps() { public void testGetHapGroupCoordinatedOps() throws Exception { doReturn(new ParcelUuid[]{BluetoothUuid.HAS}).when(mAdapterService) .getRemoteUuids(any(BluetoothDevice.class)); testConnectingDevice(mDevice); Loading @@ -482,7 +517,12 @@ public class HapClientTest { Assert.assertEquals(3, mService.getHapGroup(mDevice3)); /* Third one has no coordinated operations support but is part of the group */ Assert.assertEquals(2, mService.getHapGroup(mDevice2)); final SynchronousResultReceiver<Integer> recv = SynchronousResultReceiver.get(); int defaultRecvValue = -1000; mServiceBinder.getHapGroup(mDevice2, mAttributionSource, recv); int hapGroup = recv.awaitResultNoInterrupt(Duration.ofMillis(TIMEOUT_MS)) .getValue(defaultRecvValue); Assert.assertEquals(2, hapGroup); } /** Loading @@ -505,7 +545,7 @@ public class HapClientTest { throw e.rethrowFromSystemServer(); } mService.selectPreset(mDevice, 0x01); mServiceBinder.selectPreset(mDevice, 0x01, mAttributionSource); verify(mNativeInterface, times(1)) .selectActivePreset(eq(mDevice), eq(0x01)); } Loading @@ -531,7 +571,7 @@ public class HapClientTest { throw e.rethrowFromSystemServer(); } mService.selectPresetForGroup(0x03, 0x01); mServiceBinder.selectPresetForGroup(0x03, 0x01, mAttributionSource); verify(mNativeInterface, times(1)) .groupSelectActivePreset(eq(0x03), eq(0x01)); } Loading @@ -546,7 +586,7 @@ public class HapClientTest { testConnectingDevice(mDevice); // Verify Native Interface call mService.switchToNextPreset(mDevice); mServiceBinder.switchToNextPreset(mDevice, mAttributionSource); verify(mNativeInterface, times(1)) .nextActivePreset(eq(mDevice)); } Loading @@ -563,7 +603,7 @@ public class HapClientTest { mNativeInterface.onFeaturesUpdate(getByteAddress(mDevice3), flags); // Verify Native Interface call mService.switchToNextPresetForGroup(0x03); mServiceBinder.switchToNextPresetForGroup(0x03, mAttributionSource); verify(mNativeInterface, times(1)).groupNextActivePreset(eq(0x03)); } Loading @@ -577,7 +617,7 @@ public class HapClientTest { testConnectingDevice(mDevice); // Verify Native Interface call mService.switchToPreviousPreset(mDevice); mServiceBinder.switchToPreviousPreset(mDevice, mAttributionSource); verify(mNativeInterface, times(1)) .previousActivePreset(eq(mDevice)); } Loading @@ -596,7 +636,7 @@ public class HapClientTest { mNativeInterface.onFeaturesUpdate(getByteAddress(mDevice), flags); // Verify Native Interface call mService.switchToPreviousPresetForGroup(0x02); mServiceBinder.switchToPreviousPresetForGroup(0x02, mAttributionSource); verify(mNativeInterface, times(1)).groupPreviousActivePreset(eq(0x02)); } Loading @@ -604,26 +644,45 @@ public class HapClientTest { * Test that getActivePresetIndex returns cached value. */ @Test public void testGetActivePresetIndex() { public void testGetActivePresetIndex() throws Exception { doReturn(new ParcelUuid[]{BluetoothUuid.HAS}).when(mAdapterService) .getRemoteUuids(any(BluetoothDevice.class)); testConnectingDevice(mDevice); testOnPresetSelected(mDevice, 0x01); // Verify cached value Assert.assertEquals(0x01, mService.getActivePresetIndex(mDevice)); // Verify cached value via binder final SynchronousResultReceiver<Integer> recv = SynchronousResultReceiver.get(); int defaultRecvValue = -1000; mServiceBinder.getActivePresetIndex(mDevice, mAttributionSource, recv); int presetIndex = recv.awaitResultNoInterrupt(Duration.ofMillis(TIMEOUT_MS)) .getValue(defaultRecvValue); Assert.assertEquals(0x01, presetIndex); } /** * Test that getActivePresetInfo returns cached value for valid parameters. */ @Test public void testGetActivePresetInfo() { public void testGetPresetInfoAndActivePresetInfo() throws Exception { doReturn(new ParcelUuid[]{BluetoothUuid.HAS}).when(mAdapterService) .getRemoteUuids(any(BluetoothDevice.class)); testConnectingDevice(mDevice2); // Check when active preset is not known yet final SynchronousResultReceiver<List<BluetoothHapPresetInfo>> presetListRecv = SynchronousResultReceiver.get(); mServiceBinder.getAllPresetInfo(mDevice2, mAttributionSource, presetListRecv); List<BluetoothHapPresetInfo> presetList = presetListRecv.awaitResultNoInterrupt( Duration.ofMillis(TIMEOUT_MS)).getValue(null); final SynchronousResultReceiver<BluetoothHapPresetInfo> presetRecv = SynchronousResultReceiver.get(); mServiceBinder.getPresetInfo(mDevice2, 0x01, mAttributionSource, presetRecv); BluetoothHapPresetInfo presetInfo = presetRecv.awaitResultNoInterrupt( Duration.ofMillis(TIMEOUT_MS)).getValue(null); Assert.assertTrue(presetList.contains(presetInfo)); Assert.assertEquals(0x01, presetInfo.getIndex()); Assert.assertEquals(BluetoothHapClient.PRESET_INDEX_UNAVAILABLE, mService.getActivePresetIndex(mDevice2)); Assert.assertEquals(null, mService.getActivePresetInfo(mDevice2)); Loading @@ -633,9 +692,13 @@ public class HapClientTest { // Check when active preset is known Assert.assertEquals(0x01, mService.getActivePresetIndex(mDevice2)); BluetoothHapPresetInfo info = mService.getActivePresetInfo(mDevice2); final SynchronousResultReceiver<BluetoothHapPresetInfo> recv = SynchronousResultReceiver.get(); mServiceBinder.getActivePresetInfo(mDevice2, mAttributionSource, recv); BluetoothHapPresetInfo info = recv.awaitResultNoInterrupt(Duration.ofMillis(TIMEOUT_MS)) .getValue(null); Assert.assertNotNull(info); Assert.assertEquals(0x01, info.getIndex()); Assert.assertEquals("One", info.getName()); } /** Loading @@ -647,7 +710,7 @@ public class HapClientTest { .getRemoteUuids(any(BluetoothDevice.class)); testConnectingDevice(mDevice); mService.setPresetName(mDevice, 0x00, "ExamplePresetName"); mServiceBinder.setPresetName(mDevice, 0x00, "ExamplePresetName", mAttributionSource); verify(mNativeInterface, times(0)) .setPresetName(eq(mDevice), eq(0x00), eq("ExamplePresetName")); try { Loading Loading @@ -678,7 +741,8 @@ public class HapClientTest { int flags = 0x21; mNativeInterface.onFeaturesUpdate(getByteAddress(mDevice), flags); mService.setPresetNameForGroup(test_group, 0x00, "ExamplePresetName"); mServiceBinder.setPresetNameForGroup( test_group, 0x00, "ExamplePresetName", mAttributionSource); try { verify(mCallback, after(TIMEOUT_MS).times(1)).onSetPresetNameForGroupFailed(eq(test_group), eq(BluetoothStatusCodes.ERROR_HAP_INVALID_PRESET_INDEX)); Loading Loading @@ -937,6 +1001,57 @@ public class HapClientTest { } } @Test public void testServiceBinderGetDevicesMatchingConnectionStates() throws Exception { final SynchronousResultReceiver<List<BluetoothDevice>> recv = SynchronousResultReceiver.get(); mServiceBinder.getDevicesMatchingConnectionStates(null, mAttributionSource, recv); List<BluetoothDevice> devices = recv.awaitResultNoInterrupt(Duration.ofMillis(TIMEOUT_MS)) .getValue(null); Assert.assertEquals(0, devices.size()); } @Test public void testServiceBinderSetConnectionPolicy() throws Exception { final SynchronousResultReceiver<Boolean> recv = SynchronousResultReceiver.get(); boolean defaultRecvValue = false; mServiceBinder.setConnectionPolicy( mDevice, BluetoothProfile.CONNECTION_POLICY_UNKNOWN, mAttributionSource, recv); Assert.assertTrue(recv.awaitResultNoInterrupt(Duration.ofMillis(TIMEOUT_MS)) .getValue(defaultRecvValue)); verify(mDatabaseManager).setProfileConnectionPolicy( mDevice, BluetoothProfile.HAP_CLIENT, BluetoothProfile.CONNECTION_POLICY_UNKNOWN); } @Test public void testServiceBinderGetFeatures() throws Exception { final SynchronousResultReceiver<Integer> recv = SynchronousResultReceiver.get(); int defaultRecvValue = -1000; mServiceBinder.getFeatures(mDevice, mAttributionSource, recv); int features = recv.awaitResultNoInterrupt(Duration.ofMillis(TIMEOUT_MS)) .getValue(defaultRecvValue); Assert.assertEquals(0x00, features); } @Test public void testServiceBinderRegisterUnregisterCallback() throws Exception { IBluetoothHapClientCallback callback = Mockito.mock(IBluetoothHapClientCallback.class); Binder binder = Mockito.mock(Binder.class); when(callback.asBinder()).thenReturn(binder); int size = mService.mCallbacks.getRegisteredCallbackCount(); SynchronousResultReceiver<Void> recv = SynchronousResultReceiver.get(); mServiceBinder.registerCallback(callback, mAttributionSource, recv); recv.awaitResultNoInterrupt(Duration.ofMillis(TIMEOUT_MS)).getValue(null); Assert.assertEquals(size + 1, mService.mCallbacks.getRegisteredCallbackCount()); recv = SynchronousResultReceiver.get(); mServiceBinder.unregisterCallback(callback, mAttributionSource, recv); recv.awaitResultNoInterrupt(Duration.ofMillis(TIMEOUT_MS)).getValue(null); Assert.assertEquals(size, mService.mCallbacks.getRegisteredCallbackCount()); } /** * Helper function to test device connecting */ Loading Loading
android/app/src/com/android/bluetooth/hap/HapClientService.java +5 −0 Original line number Diff line number Diff line Loading @@ -1209,6 +1209,8 @@ public class HapClientService extends ProfileService { @VisibleForTesting static class BluetoothHapClientBinder extends IBluetoothHapClient.Stub implements IProfileServiceBinder { @VisibleForTesting boolean mIsTesting = false; private HapClientService mService; BluetoothHapClientBinder(HapClientService svc) { Loading @@ -1216,6 +1218,9 @@ public class HapClientService extends ProfileService { } private HapClientService getService(AttributionSource source) { if (mIsTesting) { return mService; } if (!Utils.checkCallerIsSystemOrActiveUser(TAG) || !Utils.checkServiceAvailable(mService, TAG) || !Utils.checkConnectPermissionForDataDelivery(mService, source, TAG)) { Loading
android/app/tests/unit/src/com/android/bluetooth/hap/HapClientTest.java +149 −34 Original line number Diff line number Diff line Loading @@ -17,9 +17,26 @@ package com.android.bluetooth.hap; import static org.mockito.Mockito.*; import android.bluetooth.*; import static org.mockito.Mockito.after; import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.anyString; import static org.mockito.Mockito.doCallRealMethod; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothHapClient; import android.bluetooth.BluetoothHapPresetInfo; import android.bluetooth.BluetoothProfile; import android.bluetooth.BluetoothStatusCodes; import android.bluetooth.BluetoothUuid; import android.bluetooth.IBluetoothHapClientCallback; import android.content.AttributionSource; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; Loading @@ -28,32 +45,32 @@ import android.os.Binder; import android.os.Looper; import android.os.ParcelUuid; import android.os.RemoteException; import android.util.Log; import androidx.test.InstrumentationRegistry; import androidx.test.filters.MediumTest; import androidx.test.rule.ServiceTestRule; import androidx.test.runner.AndroidJUnit4; import com.android.bluetooth.R; import com.android.bluetooth.TestUtils; import com.android.bluetooth.Utils; import com.android.bluetooth.btservice.AdapterService; import com.android.bluetooth.btservice.ServiceFactory; import com.android.bluetooth.btservice.storage.DatabaseManager; import com.android.bluetooth.csip.CsipSetCoordinatorService; import com.android.bluetooth.x.com.android.modules.utils.SynchronousResultReceiver; import org.junit.After; import org.junit.Assert; import org.junit.Assume; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import java.time.Duration; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; Loading @@ -77,6 +94,8 @@ public class HapClientTest { private BluetoothDevice mDevice3; private Context mTargetContext; private HapClientService mService; private HapClientService.BluetoothHapClientBinder mServiceBinder; private AttributionSource mAttributionSource; private HasIntentReceiver mHasIntentReceiver; private HashMap<BluetoothDevice, LinkedBlockingQueue<Intent>> mIntentQueue; Loading Loading @@ -116,11 +135,14 @@ public class HapClientTest { doReturn(true, false).when(mAdapterService).isStartedProfile(anyString()); mAdapter = BluetoothAdapter.getDefaultAdapter(); mAttributionSource = mAdapter.getAttributionSource(); startService(); mService.mHapClientNativeInterface = mNativeInterface; mService.mFactory = mServiceFactory; doReturn(mCsipService).when(mServiceFactory).getCsipSetCoordinatorService(); mServiceBinder = (HapClientService.BluetoothHapClientBinder) mService.initBinder(); mServiceBinder.mIsTesting = true; // Set up the State Changed receiver IntentFilter filter = new IntentFilter(); Loading Loading @@ -260,7 +282,7 @@ public class HapClientTest { * Test get/set policy for BluetoothDevice */ @Test public void testGetSetPolicy() { public void testGetSetPolicy() throws Exception { when(mDatabaseManager .getProfileConnectionPolicy(mDevice, BluetoothProfile.HAP_CLIENT)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_UNKNOWN); Loading @@ -278,9 +300,14 @@ public class HapClientTest { when(mDatabaseManager .getProfileConnectionPolicy(mDevice, BluetoothProfile.HAP_CLIENT)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); // call getConnectionPolicy via binder final SynchronousResultReceiver<Integer> recv = SynchronousResultReceiver.get(); int defaultRecvValue = -1000; mServiceBinder.getConnectionPolicy(mDevice, mAttributionSource, recv); int policy = recv.awaitResultNoInterrupt(Duration.ofMillis(TIMEOUT_MS)) .getValue(defaultRecvValue); Assert.assertEquals("Setting device policy to POLICY_ALLOWED", BluetoothProfile.CONNECTION_POLICY_ALLOWED, mService.getConnectionPolicy(mDevice)); BluetoothProfile.CONNECTION_POLICY_ALLOWED, policy); } /** Loading Loading @@ -398,7 +425,7 @@ public class HapClientTest { * Test that an outgoing connection times out */ @Test public void testOutgoingConnectTimeout() { public void testOutgoingConnectTimeout() throws Exception { // Update the device policy so okToConnect() returns true when(mDatabaseManager .getProfileConnectionPolicy(mDevice, BluetoothProfile.HAP_CLIENT)) Loading @@ -415,19 +442,22 @@ public class HapClientTest { Assert.assertEquals(BluetoothProfile.STATE_CONNECTING, mService.getConnectionState(mDevice)); // Verify the connection state broadcast, and that we are in Disconnected state // Verify the connection state broadcast, and that we are in Disconnected state via binder verifyConnectionStateIntent(HapClientStateMachine.sConnectTimeoutMs * 2, mDevice, BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_CONNECTING); Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTED, mService.getConnectionState(mDevice)); mDevice, BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_CONNECTING); final SynchronousResultReceiver<Integer> recv = SynchronousResultReceiver.get(); int defaultRecvValue = -1000; mServiceBinder.getConnectionState(mDevice, mAttributionSource, recv); int state = recv.awaitResultNoInterrupt(Duration.ofMillis(TIMEOUT_MS)) .getValue(defaultRecvValue); Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTED, state); } /** * Test that an outgoing connection to two device that have HAS UUID is successful */ @Test public void testConnectTwo() { public void testConnectTwo() throws Exception { doReturn(new ParcelUuid[]{BluetoothUuid.HAS}).when(mAdapterService) .getRemoteUuids(any(BluetoothDevice.class)); Loading @@ -438,7 +468,12 @@ public class HapClientTest { BluetoothDevice Device2 = TestUtils.getTestDevice(mAdapter, 1); testConnectingDevice(Device2); List<BluetoothDevice> devices = mService.getConnectedDevices(); // indirect call of mService.getConnectedDevices to test BluetoothHearingAidBinder final SynchronousResultReceiver<List<BluetoothDevice>> recv = SynchronousResultReceiver.get(); mServiceBinder.getConnectedDevices(mAttributionSource, recv); List<BluetoothDevice> devices = recv.awaitResultNoInterrupt(Duration.ofMillis(TIMEOUT_MS)) .getValue(null); Assert.assertTrue(devices.contains(mDevice)); Assert.assertTrue(devices.contains(Device2)); Assert.assertNotEquals(mDevice, Device2); Loading @@ -457,7 +492,7 @@ public class HapClientTest { * Test getting HAS coordinated sets. */ @Test public void testGetHapGroupCoordinatedOps() { public void testGetHapGroupCoordinatedOps() throws Exception { doReturn(new ParcelUuid[]{BluetoothUuid.HAS}).when(mAdapterService) .getRemoteUuids(any(BluetoothDevice.class)); testConnectingDevice(mDevice); Loading @@ -482,7 +517,12 @@ public class HapClientTest { Assert.assertEquals(3, mService.getHapGroup(mDevice3)); /* Third one has no coordinated operations support but is part of the group */ Assert.assertEquals(2, mService.getHapGroup(mDevice2)); final SynchronousResultReceiver<Integer> recv = SynchronousResultReceiver.get(); int defaultRecvValue = -1000; mServiceBinder.getHapGroup(mDevice2, mAttributionSource, recv); int hapGroup = recv.awaitResultNoInterrupt(Duration.ofMillis(TIMEOUT_MS)) .getValue(defaultRecvValue); Assert.assertEquals(2, hapGroup); } /** Loading @@ -505,7 +545,7 @@ public class HapClientTest { throw e.rethrowFromSystemServer(); } mService.selectPreset(mDevice, 0x01); mServiceBinder.selectPreset(mDevice, 0x01, mAttributionSource); verify(mNativeInterface, times(1)) .selectActivePreset(eq(mDevice), eq(0x01)); } Loading @@ -531,7 +571,7 @@ public class HapClientTest { throw e.rethrowFromSystemServer(); } mService.selectPresetForGroup(0x03, 0x01); mServiceBinder.selectPresetForGroup(0x03, 0x01, mAttributionSource); verify(mNativeInterface, times(1)) .groupSelectActivePreset(eq(0x03), eq(0x01)); } Loading @@ -546,7 +586,7 @@ public class HapClientTest { testConnectingDevice(mDevice); // Verify Native Interface call mService.switchToNextPreset(mDevice); mServiceBinder.switchToNextPreset(mDevice, mAttributionSource); verify(mNativeInterface, times(1)) .nextActivePreset(eq(mDevice)); } Loading @@ -563,7 +603,7 @@ public class HapClientTest { mNativeInterface.onFeaturesUpdate(getByteAddress(mDevice3), flags); // Verify Native Interface call mService.switchToNextPresetForGroup(0x03); mServiceBinder.switchToNextPresetForGroup(0x03, mAttributionSource); verify(mNativeInterface, times(1)).groupNextActivePreset(eq(0x03)); } Loading @@ -577,7 +617,7 @@ public class HapClientTest { testConnectingDevice(mDevice); // Verify Native Interface call mService.switchToPreviousPreset(mDevice); mServiceBinder.switchToPreviousPreset(mDevice, mAttributionSource); verify(mNativeInterface, times(1)) .previousActivePreset(eq(mDevice)); } Loading @@ -596,7 +636,7 @@ public class HapClientTest { mNativeInterface.onFeaturesUpdate(getByteAddress(mDevice), flags); // Verify Native Interface call mService.switchToPreviousPresetForGroup(0x02); mServiceBinder.switchToPreviousPresetForGroup(0x02, mAttributionSource); verify(mNativeInterface, times(1)).groupPreviousActivePreset(eq(0x02)); } Loading @@ -604,26 +644,45 @@ public class HapClientTest { * Test that getActivePresetIndex returns cached value. */ @Test public void testGetActivePresetIndex() { public void testGetActivePresetIndex() throws Exception { doReturn(new ParcelUuid[]{BluetoothUuid.HAS}).when(mAdapterService) .getRemoteUuids(any(BluetoothDevice.class)); testConnectingDevice(mDevice); testOnPresetSelected(mDevice, 0x01); // Verify cached value Assert.assertEquals(0x01, mService.getActivePresetIndex(mDevice)); // Verify cached value via binder final SynchronousResultReceiver<Integer> recv = SynchronousResultReceiver.get(); int defaultRecvValue = -1000; mServiceBinder.getActivePresetIndex(mDevice, mAttributionSource, recv); int presetIndex = recv.awaitResultNoInterrupt(Duration.ofMillis(TIMEOUT_MS)) .getValue(defaultRecvValue); Assert.assertEquals(0x01, presetIndex); } /** * Test that getActivePresetInfo returns cached value for valid parameters. */ @Test public void testGetActivePresetInfo() { public void testGetPresetInfoAndActivePresetInfo() throws Exception { doReturn(new ParcelUuid[]{BluetoothUuid.HAS}).when(mAdapterService) .getRemoteUuids(any(BluetoothDevice.class)); testConnectingDevice(mDevice2); // Check when active preset is not known yet final SynchronousResultReceiver<List<BluetoothHapPresetInfo>> presetListRecv = SynchronousResultReceiver.get(); mServiceBinder.getAllPresetInfo(mDevice2, mAttributionSource, presetListRecv); List<BluetoothHapPresetInfo> presetList = presetListRecv.awaitResultNoInterrupt( Duration.ofMillis(TIMEOUT_MS)).getValue(null); final SynchronousResultReceiver<BluetoothHapPresetInfo> presetRecv = SynchronousResultReceiver.get(); mServiceBinder.getPresetInfo(mDevice2, 0x01, mAttributionSource, presetRecv); BluetoothHapPresetInfo presetInfo = presetRecv.awaitResultNoInterrupt( Duration.ofMillis(TIMEOUT_MS)).getValue(null); Assert.assertTrue(presetList.contains(presetInfo)); Assert.assertEquals(0x01, presetInfo.getIndex()); Assert.assertEquals(BluetoothHapClient.PRESET_INDEX_UNAVAILABLE, mService.getActivePresetIndex(mDevice2)); Assert.assertEquals(null, mService.getActivePresetInfo(mDevice2)); Loading @@ -633,9 +692,13 @@ public class HapClientTest { // Check when active preset is known Assert.assertEquals(0x01, mService.getActivePresetIndex(mDevice2)); BluetoothHapPresetInfo info = mService.getActivePresetInfo(mDevice2); final SynchronousResultReceiver<BluetoothHapPresetInfo> recv = SynchronousResultReceiver.get(); mServiceBinder.getActivePresetInfo(mDevice2, mAttributionSource, recv); BluetoothHapPresetInfo info = recv.awaitResultNoInterrupt(Duration.ofMillis(TIMEOUT_MS)) .getValue(null); Assert.assertNotNull(info); Assert.assertEquals(0x01, info.getIndex()); Assert.assertEquals("One", info.getName()); } /** Loading @@ -647,7 +710,7 @@ public class HapClientTest { .getRemoteUuids(any(BluetoothDevice.class)); testConnectingDevice(mDevice); mService.setPresetName(mDevice, 0x00, "ExamplePresetName"); mServiceBinder.setPresetName(mDevice, 0x00, "ExamplePresetName", mAttributionSource); verify(mNativeInterface, times(0)) .setPresetName(eq(mDevice), eq(0x00), eq("ExamplePresetName")); try { Loading Loading @@ -678,7 +741,8 @@ public class HapClientTest { int flags = 0x21; mNativeInterface.onFeaturesUpdate(getByteAddress(mDevice), flags); mService.setPresetNameForGroup(test_group, 0x00, "ExamplePresetName"); mServiceBinder.setPresetNameForGroup( test_group, 0x00, "ExamplePresetName", mAttributionSource); try { verify(mCallback, after(TIMEOUT_MS).times(1)).onSetPresetNameForGroupFailed(eq(test_group), eq(BluetoothStatusCodes.ERROR_HAP_INVALID_PRESET_INDEX)); Loading Loading @@ -937,6 +1001,57 @@ public class HapClientTest { } } @Test public void testServiceBinderGetDevicesMatchingConnectionStates() throws Exception { final SynchronousResultReceiver<List<BluetoothDevice>> recv = SynchronousResultReceiver.get(); mServiceBinder.getDevicesMatchingConnectionStates(null, mAttributionSource, recv); List<BluetoothDevice> devices = recv.awaitResultNoInterrupt(Duration.ofMillis(TIMEOUT_MS)) .getValue(null); Assert.assertEquals(0, devices.size()); } @Test public void testServiceBinderSetConnectionPolicy() throws Exception { final SynchronousResultReceiver<Boolean> recv = SynchronousResultReceiver.get(); boolean defaultRecvValue = false; mServiceBinder.setConnectionPolicy( mDevice, BluetoothProfile.CONNECTION_POLICY_UNKNOWN, mAttributionSource, recv); Assert.assertTrue(recv.awaitResultNoInterrupt(Duration.ofMillis(TIMEOUT_MS)) .getValue(defaultRecvValue)); verify(mDatabaseManager).setProfileConnectionPolicy( mDevice, BluetoothProfile.HAP_CLIENT, BluetoothProfile.CONNECTION_POLICY_UNKNOWN); } @Test public void testServiceBinderGetFeatures() throws Exception { final SynchronousResultReceiver<Integer> recv = SynchronousResultReceiver.get(); int defaultRecvValue = -1000; mServiceBinder.getFeatures(mDevice, mAttributionSource, recv); int features = recv.awaitResultNoInterrupt(Duration.ofMillis(TIMEOUT_MS)) .getValue(defaultRecvValue); Assert.assertEquals(0x00, features); } @Test public void testServiceBinderRegisterUnregisterCallback() throws Exception { IBluetoothHapClientCallback callback = Mockito.mock(IBluetoothHapClientCallback.class); Binder binder = Mockito.mock(Binder.class); when(callback.asBinder()).thenReturn(binder); int size = mService.mCallbacks.getRegisteredCallbackCount(); SynchronousResultReceiver<Void> recv = SynchronousResultReceiver.get(); mServiceBinder.registerCallback(callback, mAttributionSource, recv); recv.awaitResultNoInterrupt(Duration.ofMillis(TIMEOUT_MS)).getValue(null); Assert.assertEquals(size + 1, mService.mCallbacks.getRegisteredCallbackCount()); recv = SynchronousResultReceiver.get(); mServiceBinder.unregisterCallback(callback, mAttributionSource, recv); recv.awaitResultNoInterrupt(Duration.ofMillis(TIMEOUT_MS)).getValue(null); Assert.assertEquals(size, mService.mCallbacks.getRegisteredCallbackCount()); } /** * Helper function to test device connecting */ Loading