diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2022-05-25 23:25:26 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2022-05-25 23:25:26 +0000 |
commit | 1c0250fd299fe3d3d0916604503a19c6f90e5aa5 (patch) | |
tree | 482254ab0e84e630dbf3ebbc5ed54067edb67035 | |
parent | a56b60dfa48b949aa0d6058d46ba02cc33b2243d (diff) | |
parent | f6745c0f487e99e46f6e96c11e31d002896dbc87 (diff) |
Snap for 8642511 from f6745c0f487e99e46f6e96c11e31d002896dbc87 to tm-release
Change-Id: I2653e6c45da69b22cf5fda60b97f63a67751be85
-rw-r--r-- | AndroidTestTemplate.xml | 15 | ||||
-rw-r--r-- | android/app/src/com/android/bluetooth/btservice/AdapterService.java | 16 | ||||
-rw-r--r-- | android/app/src/com/android/bluetooth/le_audio/LeAudioService.java | 39 | ||||
-rw-r--r-- | android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioServiceTest.java | 161 | ||||
-rw-r--r-- | system/bta/csis/csis_client.cc | 12 | ||||
-rw-r--r-- | system/bta/hearing_aid/hearing_aid.cc | 4 | ||||
-rw-r--r-- | system/bta/le_audio/client.cc | 13 | ||||
-rw-r--r-- | system/bta/vc/vc.cc | 13 | ||||
-rw-r--r-- | system/gd/AndroidTestTemplate.xml | 15 | ||||
-rw-r--r-- | system/test/Android.bp | 1 |
10 files changed, 250 insertions, 39 deletions
diff --git a/AndroidTestTemplate.xml b/AndroidTestTemplate.xml index 601be93108..4fb4bf9f76 100644 --- a/AndroidTestTemplate.xml +++ b/AndroidTestTemplate.xml @@ -17,10 +17,11 @@ <option name="test-suite-tag" value="apct" /> <option name="test-suite-tag" value="apct-native" /> <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer" /> - <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer"> - <option name="cleanup" value="true" /> - <option name="push" value="{MODULE}->/data/local/tmp/{MODULE}" /> - </target_preparer> + <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher"> + <option name="cleanup" value="true" /> + <option name="push" value="{MODULE}->/data/local/tmp/{MODULE}" /> + <option name="append-bitness" value="true" /> + </target_preparer> <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer"> <option name="run-command" value="settings put global ble_scan_always_enabled 0" /> <option name="run-command" value="svc bluetooth disable" /> @@ -33,4 +34,10 @@ <option name="module-name" value="{MODULE}" /> <option name="run-test-as" value="0" /> </test> + + <!-- Only run tests in MTS if the Bluetooth Mainline module is installed. --> + <object type="module_controller" + class="com.android.tradefed.testtype.suite.module.MainlineTestModuleController"> + <option name="mainline-module-package-name" value="com.google.android.bluetooth" /> + </object> </configuration> diff --git a/android/app/src/com/android/bluetooth/btservice/AdapterService.java b/android/app/src/com/android/bluetooth/btservice/AdapterService.java index b60b01ff81..e0185f8b6f 100644 --- a/android/app/src/com/android/bluetooth/btservice/AdapterService.java +++ b/android/app/src/com/android/bluetooth/btservice/AdapterService.java @@ -148,13 +148,14 @@ import java.time.Duration; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.Executor; import java.util.function.Predicate; @@ -282,8 +283,7 @@ public class AdapterService extends Service { private boolean mQuietmode = false; private HashMap<String, CallerInfo> mBondAttemptCallerInfo = new HashMap<>(); - private final Map<UUID, RfcommListenerData> mBluetoothServerSockets = - Collections.synchronizedMap(new HashMap<>()); + private final Map<UUID, RfcommListenerData> mBluetoothServerSockets = new ConcurrentHashMap<>(); private final Executor mSocketServersExecutor = r -> new Thread(r).start(); private AlarmManager mAlarmManager; @@ -1491,11 +1491,11 @@ public class AdapterService extends Service { } private void stopRfcommServerSockets() { - synchronized (mBluetoothServerSockets) { - mBluetoothServerSockets.forEach((key, value) -> { - mBluetoothServerSockets.remove(key); - value.closeServerAndPendingSockets(mHandler); - }); + Iterator<Map.Entry<UUID, RfcommListenerData>> socketsIterator = + mBluetoothServerSockets.entrySet().iterator(); + while (socketsIterator.hasNext()) { + socketsIterator.next().getValue().closeServerAndPendingSockets(mHandler); + socketsIterator.remove(); } } diff --git a/android/app/src/com/android/bluetooth/le_audio/LeAudioService.java b/android/app/src/com/android/bluetooth/le_audio/LeAudioService.java index 42c4c5aeeb..33fa96f3c6 100644 --- a/android/app/src/com/android/bluetooth/le_audio/LeAudioService.java +++ b/android/app/src/com/android/bluetooth/le_audio/LeAudioService.java @@ -139,7 +139,7 @@ public class LeAudioService extends ProfileService { mIsActive = false; mActiveContexts = ACTIVE_CONTEXTS_NONE; mCodecStatus = null; - mLostDevicesWhileStreaming = new ArrayList<>(); + mLostLeadDeviceWhileStreaming = null; } public Boolean mIsConnected; @@ -147,7 +147,7 @@ public class LeAudioService extends ProfileService { public Integer mActiveContexts; public BluetoothLeAudioCodecStatus mCodecStatus; /* This can be non empty only for the streaming time */ - List<BluetoothDevice> mLostDevicesWhileStreaming; + BluetoothDevice mLostLeadDeviceWhileStreaming; } List<BluetoothLeAudioCodecConfig> mInputLocalCodecCapabilities = new ArrayList<>(); @@ -1066,18 +1066,19 @@ public class LeAudioService extends ProfileService { } private void clearLostDevicesWhileStreaming(LeAudioGroupDescriptor descriptor) { - for (BluetoothDevice dev : descriptor.mLostDevicesWhileStreaming) { - LeAudioStateMachine sm = mStateMachines.get(dev); - if (sm == null) { - continue; - } + if (DBG) { + Log.d(TAG, " lost dev: " + descriptor.mLostLeadDeviceWhileStreaming); + } + LeAudioStateMachine sm = mStateMachines.get(descriptor.mLostLeadDeviceWhileStreaming); + if (sm != null) { LeAudioStackEvent stackEvent = new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); - stackEvent.device = dev; + stackEvent.device = descriptor.mLostLeadDeviceWhileStreaming; stackEvent.valueInt1 = LeAudioStackEvent.CONNECTION_STATE_DISCONNECTED; sm.sendMessage(LeAudioStateMachine.STACK_EVENT, stackEvent); } + descriptor.mLostLeadDeviceWhileStreaming = null; } // Suppressed since this is part of a local process @@ -1110,14 +1111,17 @@ public class LeAudioService extends ProfileService { mActiveAudioOutDevice) || Objects.equals(device, mActiveAudioInDevice)) && (getConnectedPeerDevices(groupId).size() > 1)) { - descriptor.mLostDevicesWhileStreaming.add(device); + + if (DBG) Log.d(TAG, "Adding to lost devices : " + device); + descriptor.mLostLeadDeviceWhileStreaming = device; return; } break; case LeAudioStackEvent.CONNECTION_STATE_CONNECTED: case LeAudioStackEvent.CONNECTION_STATE_CONNECTING: if (descriptor != null) { - descriptor.mLostDevicesWhileStreaming.remove(device); + if (DBG) Log.d(TAG, "Removing from lost devices : " + device); + descriptor.mLostLeadDeviceWhileStreaming = null; /* Try to connect other devices from the group */ connectSet(device); } @@ -1254,6 +1258,7 @@ public class LeAudioService extends ProfileService { ACTIVE_CONTEXTS_NONE, descriptor.mIsActive); notifyGroupStatus = true; /* Clear lost devices */ + if (DBG) Log.d(TAG, "Clear for group: " + groupId); clearLostDevicesWhileStreaming(descriptor); } } else { @@ -1538,6 +1543,15 @@ public class LeAudioService extends ProfileService { return; } + List<BluetoothDevice> connectedDevices = getConnectedPeerDevices(myGroupId); + /* Let's check if the last connected device is really connected */ + if (connectedDevices.size() == 1 + && Objects.equals(connectedDevices.get(0), + descriptor.mLostLeadDeviceWhileStreaming)) { + clearLostDevicesWhileStreaming(descriptor); + return; + } + if (getConnectedPeerDevices(myGroupId).isEmpty()){ descriptor.mIsConnected = false; if (descriptor.mIsActive) { @@ -2584,9 +2598,8 @@ public class LeAudioService extends ProfileService { ProfileService.println(sb, " mActiveContexts: " + descriptor.mActiveContexts); ProfileService.println(sb, " group lead: " + getConnectedGroupLeadDevice(groupId)); ProfileService.println(sb, " first device: " + getFirstDeviceFromGroup(groupId)); - for (BluetoothDevice dev : descriptor.mLostDevicesWhileStreaming) { - ProfileService.println(sb, " lost device: " + dev); - } + ProfileService.println(sb, " lost lead device: " + + descriptor.mLostLeadDeviceWhileStreaming); } } } diff --git a/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioServiceTest.java index 8a8901e9e0..ae41ce046c 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioServiceTest.java @@ -26,7 +26,11 @@ import static org.mockito.Mockito.anyString; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.eq; import static org.mockito.Mockito.when; +import static org.mockito.Mockito.timeout; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; @@ -42,6 +46,7 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.media.AudioManager; +import android.media.BluetoothProfileConnectionInfo; import android.os.ParcelUuid; import androidx.test.InstrumentationRegistry; @@ -68,6 +73,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Objects; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeoutException; @@ -457,6 +463,23 @@ public class LeAudioServiceTest { .isEqualTo(BluetoothProfile.STATE_DISCONNECTED); } + private void injectNoVerifyDeviceConnected(BluetoothDevice device) { + generateUnexpectedConnectionMessageFromNative(device, + LeAudioStackEvent.CONNECTION_STATE_CONNECTED, + LeAudioStackEvent.CONNECTION_STATE_DISCONNECTED); + } + + private void injectAndVerifyDeviceDisconnected(BluetoothDevice device) { + generateConnectionMessageFromNative(device, + LeAudioStackEvent.CONNECTION_STATE_DISCONNECTED, + LeAudioStackEvent.CONNECTION_STATE_CONNECTED); + } + + private void injectNoVerifyDeviceDisconnected(BluetoothDevice device) { + generateUnexpectedConnectionMessageFromNative(device, + LeAudioStackEvent.CONNECTION_STATE_DISCONNECTED, + LeAudioStackEvent.CONNECTION_STATE_CONNECTED); + } /** * Test that the outgoing connect/disconnect and audio switch is successful. */ @@ -1220,4 +1243,142 @@ public class LeAudioServiceTest { onGroupCodecConfChangedCallbackCalled = false; mService.mLeAudioCallbacks.unregister(leAudioCallbacks); } + + private void verifyActiveDeviceStateIntent(int timeoutMs, BluetoothDevice device) { + Intent intent = TestUtils.waitForIntent(timeoutMs, mDeviceQueueMap.get(device)); + assertThat(intent).isNotNull(); + assertThat(intent.getAction()) + .isEqualTo(BluetoothLeAudio.ACTION_LE_AUDIO_ACTIVE_DEVICE_CHANGED); + assertThat(device).isEqualTo(intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)); + } + + /** + * Test native interface group status message handling + */ + @Test + public void testLeadGroupDeviceDisconnects() { + int groupId = 1; + int direction = 1; + int snkAudioLocation = 3; + int srcAudioLocation = 4; + int availableContexts = 5; + int groupStatus = LeAudioStackEvent.GROUP_STATUS_ACTIVE; + BluetoothDevice leadDevice; + BluetoothDevice memberDevice = mLeftDevice; + + doReturn(true).when(mNativeInterface).connectLeAudio(any(BluetoothDevice.class)); + connectTestDevice(mLeftDevice, groupId); + connectTestDevice(mRightDevice, groupId); + + leadDevice = mService.getConnectedGroupLeadDevice(groupId); + if (Objects.equals(leadDevice, mLeftDevice)) { + memberDevice = mRightDevice; + } + + assertThat(mService.setActiveDevice(leadDevice)).isTrue(); + + //Add location support + LeAudioStackEvent audioConfChangedEvent = + new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_AUDIO_CONF_CHANGED); + audioConfChangedEvent.valueInt1 = direction; + audioConfChangedEvent.valueInt2 = groupId; + audioConfChangedEvent.valueInt3 = snkAudioLocation; + audioConfChangedEvent.valueInt4 = srcAudioLocation; + audioConfChangedEvent.valueInt5 = availableContexts; + mService.messageFromNative(audioConfChangedEvent); + + //Set group and device as active + LeAudioStackEvent groupStatusChangedEvent = + new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_GROUP_STATUS_CHANGED); + groupStatusChangedEvent.valueInt1 = groupId; + groupStatusChangedEvent.valueInt2 = groupStatus; + mService.messageFromNative(groupStatusChangedEvent); + + assertThat(mService.getActiveDevices().contains(leadDevice)).isTrue(); + verify(mAudioManager, times(1)).handleBluetoothActiveDeviceChanged(eq(leadDevice), any(), + any(BluetoothProfileConnectionInfo.class)); + + verifyActiveDeviceStateIntent(TIMEOUT_MS, leadDevice); + injectNoVerifyDeviceDisconnected(leadDevice); + + // We should not change the audio device + assertThat(mService.getConnectionState(leadDevice)) + .isEqualTo(BluetoothProfile.STATE_CONNECTED); + + injectAndVerifyDeviceDisconnected(memberDevice); + + // Verify the connection state broadcast, and that we are in Connecting state + verifyConnectionStateIntent(TIMEOUT_MS, leadDevice, BluetoothProfile.STATE_DISCONNECTED, + BluetoothProfile.STATE_CONNECTED); + + verify(mAudioManager, times(1)).handleBluetoothActiveDeviceChanged(any(), eq(leadDevice), + any(BluetoothProfileConnectionInfo.class)); + + } + + /** + * Test native interface group status message handling + */ + @Test + public void testLeadGroupDeviceReconnects() { + int groupId = 1; + int direction = 1; + int snkAudioLocation = 3; + int srcAudioLocation = 4; + int availableContexts = 5; + int groupStatus = LeAudioStackEvent.GROUP_STATUS_ACTIVE; + BluetoothDevice leadDevice; + BluetoothDevice memberDevice = mLeftDevice; + + doReturn(true).when(mNativeInterface).connectLeAudio(any(BluetoothDevice.class)); + connectTestDevice(mLeftDevice, groupId); + connectTestDevice(mRightDevice, groupId); + + leadDevice = mService.getConnectedGroupLeadDevice(groupId); + if (Objects.equals(leadDevice, mLeftDevice)) { + memberDevice = mRightDevice; + } + + assertThat(mService.setActiveDevice(leadDevice)).isTrue(); + + //Add location support + LeAudioStackEvent audioConfChangedEvent = + new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_AUDIO_CONF_CHANGED); + audioConfChangedEvent.valueInt1 = direction; + audioConfChangedEvent.valueInt2 = groupId; + audioConfChangedEvent.valueInt3 = snkAudioLocation; + audioConfChangedEvent.valueInt4 = srcAudioLocation; + audioConfChangedEvent.valueInt5 = availableContexts; + mService.messageFromNative(audioConfChangedEvent); + + //Set group and device as active + LeAudioStackEvent groupStatusChangedEvent = + new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_GROUP_STATUS_CHANGED); + groupStatusChangedEvent.valueInt1 = groupId; + groupStatusChangedEvent.valueInt2 = groupStatus; + mService.messageFromNative(groupStatusChangedEvent); + + assertThat(mService.getActiveDevices().contains(leadDevice)).isTrue(); + verify(mAudioManager, times(1)).handleBluetoothActiveDeviceChanged(eq(leadDevice), any(), + any(BluetoothProfileConnectionInfo.class)); + + verifyActiveDeviceStateIntent(TIMEOUT_MS, leadDevice); + /* We don't want to distribute DISCONNECTION event, instead will try to reconnect + * (in native) + */ + injectNoVerifyDeviceDisconnected(leadDevice); + assertThat(mService.getConnectionState(leadDevice)) + .isEqualTo(BluetoothProfile.STATE_CONNECTED); + + /* Reconnect device, there should be no intent about that, as device was pretending + * connected + */ + injectNoVerifyDeviceConnected(leadDevice); + + injectAndVerifyDeviceDisconnected(memberDevice); + injectAndVerifyDeviceDisconnected(leadDevice); + + verify(mAudioManager, times(1)).handleBluetoothActiveDeviceChanged(eq(null), eq(leadDevice), + any(BluetoothProfileConnectionInfo.class)); + } } diff --git a/system/bta/csis/csis_client.cc b/system/bta/csis/csis_client.cc index 6fdf67c871..a1199f6c28 100644 --- a/system/bta/csis/csis_client.cc +++ b/system/bta/csis/csis_client.cc @@ -1558,9 +1558,15 @@ class CsisClientImpl : public CsisClient { OnGattNotification(p_data->notify); break; - case BTA_GATTC_ENC_CMPL_CB_EVT: - OnLeEncryptionComplete(p_data->enc_cmpl.remote_bda, BTM_SUCCESS); - break; + case BTA_GATTC_ENC_CMPL_CB_EVT: { + uint8_t encryption_status; + if (BTM_IsEncrypted(p_data->enc_cmpl.remote_bda, BT_TRANSPORT_LE)) { + encryption_status = BTM_SUCCESS; + } else { + encryption_status = BTM_FAILED_ON_SECURITY; + } + OnLeEncryptionComplete(p_data->enc_cmpl.remote_bda, encryption_status); + } break; case BTA_GATTC_SRVC_CHG_EVT: OnGattServiceChangeEvent(p_data->remote_bda); diff --git a/system/bta/hearing_aid/hearing_aid.cc b/system/bta/hearing_aid/hearing_aid.cc index 987aaec031..ce3c4c4a3a 100644 --- a/system/bta/hearing_aid/hearing_aid.cc +++ b/system/bta/hearing_aid/hearing_aid.cc @@ -1868,7 +1868,9 @@ void hearingaid_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data) { case BTA_GATTC_ENC_CMPL_CB_EVT: if (!instance) return; - instance->OnEncryptionComplete(p_data->enc_cmpl.remote_bda, true); + instance->OnEncryptionComplete( + p_data->enc_cmpl.remote_bda, + BTM_IsEncrypted(p_data->enc_cmpl.remote_bda, BT_TRANSPORT_LE)); break; case BTA_GATTC_CONN_UPDATE_EVT: diff --git a/system/bta/le_audio/client.cc b/system/bta/le_audio/client.cc index 2f877f0097..5206f7b8b0 100644 --- a/system/bta/le_audio/client.cc +++ b/system/bta/le_audio/client.cc @@ -3634,9 +3634,16 @@ void le_audio_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data) { p_data->open.transport, p_data->open.mtu); break; - case BTA_GATTC_ENC_CMPL_CB_EVT: - instance->OnEncryptionComplete(p_data->enc_cmpl.remote_bda, BTM_SUCCESS); - break; + case BTA_GATTC_ENC_CMPL_CB_EVT: { + uint8_t encryption_status; + if (BTM_IsEncrypted(p_data->enc_cmpl.remote_bda, BT_TRANSPORT_LE)) { + encryption_status = BTM_SUCCESS; + } else { + encryption_status = BTM_FAILED_ON_SECURITY; + } + instance->OnEncryptionComplete(p_data->enc_cmpl.remote_bda, + encryption_status); + } break; case BTA_GATTC_CLOSE_EVT: instance->OnGattDisconnected( diff --git a/system/bta/vc/vc.cc b/system/bta/vc/vc.cc index d81f00c6aa..43d9ac19ec 100644 --- a/system/bta/vc/vc.cc +++ b/system/bta/vc/vc.cc @@ -35,6 +35,7 @@ #include "gd/common/strings.h" #include "osi/include/log.h" #include "osi/include/osi.h" +#include "stack/btm/btm_sec.h" #include "types/bluetooth/uuid.h" #include "types/raw_address.h" @@ -1014,9 +1015,15 @@ class VolumeControlImpl : public VolumeControl { OnNotificationEvent(n.conn_id, n.handle, n.len, n.value); } break; - case BTA_GATTC_ENC_CMPL_CB_EVT: - OnEncryptionComplete(p_data->enc_cmpl.remote_bda, BTM_SUCCESS); - break; + case BTA_GATTC_ENC_CMPL_CB_EVT: { + uint8_t encryption_status; + if (!BTM_IsEncrypted(p_data->enc_cmpl.remote_bda, BT_TRANSPORT_LE)) { + encryption_status = BTM_SUCCESS; + } else { + encryption_status = BTM_FAILED_ON_SECURITY; + } + OnEncryptionComplete(p_data->enc_cmpl.remote_bda, encryption_status); + } break; case BTA_GATTC_SRVC_CHG_EVT: OnServiceChangeEvent(p_data->remote_bda); diff --git a/system/gd/AndroidTestTemplate.xml b/system/gd/AndroidTestTemplate.xml index 601be93108..4fb4bf9f76 100644 --- a/system/gd/AndroidTestTemplate.xml +++ b/system/gd/AndroidTestTemplate.xml @@ -17,10 +17,11 @@ <option name="test-suite-tag" value="apct" /> <option name="test-suite-tag" value="apct-native" /> <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer" /> - <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer"> - <option name="cleanup" value="true" /> - <option name="push" value="{MODULE}->/data/local/tmp/{MODULE}" /> - </target_preparer> + <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher"> + <option name="cleanup" value="true" /> + <option name="push" value="{MODULE}->/data/local/tmp/{MODULE}" /> + <option name="append-bitness" value="true" /> + </target_preparer> <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer"> <option name="run-command" value="settings put global ble_scan_always_enabled 0" /> <option name="run-command" value="svc bluetooth disable" /> @@ -33,4 +34,10 @@ <option name="module-name" value="{MODULE}" /> <option name="run-test-as" value="0" /> </test> + + <!-- Only run tests in MTS if the Bluetooth Mainline module is installed. --> + <object type="module_controller" + class="com.android.tradefed.testtype.suite.module.MainlineTestModuleController"> + <option name="mainline-module-package-name" value="com.google.android.bluetooth" /> + </object> </configuration> diff --git a/system/test/Android.bp b/system/test/Android.bp index f99db16f61..8c93ff5255 100644 --- a/system/test/Android.bp +++ b/system/test/Android.bp @@ -456,6 +456,7 @@ cc_defaults { name: "mts_defaults", target: { android: { + test_config_template: ":BluetoothTestConfigTemplate", test_suites: ["mts-bluetooth",], }, }, |