diff options
276 files changed, 3907 insertions, 2454 deletions
diff --git a/Android.bp b/Android.bp index bef6c85049..29614b5d3d 100644 --- a/Android.bp +++ b/Android.bp @@ -32,9 +32,16 @@ license { } filegroup { - name: "BluetoothTestConfigTemplate", + name: "BluetoothGTestConfigTemplate", srcs: [ - "AndroidTestTemplate.xml", + "BluetoothGTestTemplate.xml", + ], +} + +filegroup { + name: "BluetoothRustTestConfigTemplate", + srcs: [ + "BluetoothRustTestTemplate.xml", ], } @@ -167,6 +174,7 @@ java_defaults { "-Xep:StringCaseLocaleUsage:ERROR", "-Xep:StringCharset:ERROR", "-Xep:SynchronizeOnNonFinalField:ERROR", + "-Xep:ThreadJoinLoop:ERROR", "-Xep:ToStringReturnsNull:ERROR", "-Xep:TruthConstantAsserts:ERROR", "-Xep:TruthIncompatibleType:ERROR", diff --git a/AndroidTestTemplate.xml b/BluetoothGTestTemplate.xml index 4083baac14..4083baac14 100644 --- a/AndroidTestTemplate.xml +++ b/BluetoothGTestTemplate.xml diff --git a/BluetoothRustTestTemplate.xml b/BluetoothRustTestTemplate.xml new file mode 100644 index 0000000000..5defd3485e --- /dev/null +++ b/BluetoothRustTestTemplate.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright 2025 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<configuration description="Runs {MODULE}."> + <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer" /> + <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> + <test class="com.android.tradefed.testtype.rust.RustBinaryTest" > + <option name="test-device-path" value="/data/local/tmp" /> + <option name="module-name" value="{MODULE}" /> + </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.android.bt" /> + <option name="mainline-module-package-name" value="com.google.android.bt" /> + </object> +</configuration>
\ No newline at end of file diff --git a/OWNERS_channel_sounding b/OWNERS_channel_sounding index f39c775033..10a8fa893a 100644 --- a/OWNERS_channel_sounding +++ b/OWNERS_channel_sounding @@ -1,3 +1,9 @@ +# Pixel DRI aliceypkuo@google.com -ashchen@google.com chienyuanhuang@google.com + +# Bluetooth Ranging DRI +steveliu@google.com + +# Bluetooth Stack Reviewer +henrichataing@google.com diff --git a/TEST_MAPPING b/TEST_MAPPING index 2b6e8f8d6e..8c32e97a23 100644 --- a/TEST_MAPPING +++ b/TEST_MAPPING @@ -78,10 +78,9 @@ { "name": "bluetooth-test-audio-hal-a2dp-provider-info" }, - // Broken - //{ - // "name": "bluetooth-test-audio-hal-aidl-leaudio-utils" - //}, + { + "name": "bluetooth-test-audio-hal-aidl-leaudio-utils" + }, { "name": "bluetooth-test-audio-hal-hfp-client-interface" }, @@ -118,10 +117,9 @@ { "name": "libbluetooth_core_rs_test" }, - // Broken - //{ - // "name": "libbluetooth_log_test" - //}, + { + "name": "libbluetooth_log_test" + }, { "name": "libbluetooth_offload_hci_test" }, @@ -315,10 +313,9 @@ { "name": "bluetooth-test-audio-hal-a2dp-provider-info" }, - // Broken - //{ - // "name": "bluetooth-test-audio-hal-aidl-leaudio-utils" - //}, + { + "name": "bluetooth-test-audio-hal-aidl-leaudio-utils" + }, { "name": "bluetooth-test-audio-hal-hfp-client-interface" }, @@ -355,10 +352,9 @@ { "name": "libbluetooth_core_rs_test" }, - // Broken - //{ - // "name": "libbluetooth_log_test" - //}, + { + "name": "libbluetooth_log_test" + }, { "name": "libbluetooth_offload_hci_test" }, diff --git a/android/app/Android.bp b/android/app/Android.bp index 81f630b436..1a1b0cd950 100644 --- a/android/app/Android.bp +++ b/android/app/Android.bp @@ -221,7 +221,7 @@ android_library { "bluetooth_flags_java_lib", "error_prone_annotations", "framework-annotations-lib", - "framework-bluetooth.impl", + "framework-bluetooth-pre-jarjar", "framework-configinfrastructure.stubs.module_lib", "framework-connectivity-t.stubs.module_lib", "framework-connectivity.stubs.module_lib", @@ -341,7 +341,7 @@ android_app { enabled: true, shrink: true, optimize: false, - ignore_warnings: false, + // ignore_warnings: false, // TODO: b/191783947 -- re-activate error proguard_flags_files: ["proguard.flags"], }, diff --git a/android/app/OWNERS b/android/app/OWNERS index 99c73be372..7b7e2e6679 100644 --- a/android/app/OWNERS +++ b/android/app/OWNERS @@ -9,6 +9,7 @@ okamil@google.com poahlo@google.com siyuanh@google.com wescande@google.com +rwt@google.com # Reviewers for Channel Sounding related files per-file /src/com/android/bluetooth/gatt/DistanceMeasurement*.java=file:/OWNERS_channel_sounding diff --git a/android/app/src/com/android/bluetooth/a2dp/A2dpNativeInterface.java b/android/app/src/com/android/bluetooth/a2dp/A2dpNativeInterface.java index 709dc954c5..67beb274d5 100644 --- a/android/app/src/com/android/bluetooth/a2dp/A2dpNativeInterface.java +++ b/android/app/src/com/android/bluetooth/a2dp/A2dpNativeInterface.java @@ -15,7 +15,7 @@ */ /* - * Defines the native inteface that is used by state machine/service to + * Defines the native interface that is used by state machine/service to * send or receive messages from the native stack. This file is registered * for the native methods in the corresponding JNI C++ file. */ @@ -34,7 +34,6 @@ import com.android.bluetooth.flags.Flags; import com.android.internal.annotations.VisibleForTesting; import java.lang.annotation.Native; - import java.util.Arrays; import java.util.List; diff --git a/android/app/src/com/android/bluetooth/bass_client/BassClientService.java b/android/app/src/com/android/bluetooth/bass_client/BassClientService.java index 2b0b63412e..df4d2e8992 100644 --- a/android/app/src/com/android/bluetooth/bass_client/BassClientService.java +++ b/android/app/src/com/android/bluetooth/bass_client/BassClientService.java @@ -28,6 +28,7 @@ import static com.android.bluetooth.flags.Flags.leaudioBigDependsOnAudioState; import static com.android.bluetooth.flags.Flags.leaudioBroadcastApiGetLocalMetadata; import static com.android.bluetooth.flags.Flags.leaudioBroadcastAssistantPeripheralEntrustment; import static com.android.bluetooth.flags.Flags.leaudioBroadcastExtractPeriodicScannerFromStateMachine; +import static com.android.bluetooth.flags.Flags.leaudioBroadcastPreventResumeInterruption; import static com.android.bluetooth.flags.Flags.leaudioBroadcastResyncHelper; import static com.android.bluetooth.flags.Flags.leaudioMonitorUnicastSourceWhenManagedByBroadcastDelegator; import static com.android.bluetooth.flags.Flags.leaudioSortScansToSyncByFails; @@ -38,7 +39,6 @@ import android.annotation.RequiresPermission; import android.annotation.SuppressLint; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; -import android.bluetooth.BluetoothGatt; import android.bluetooth.BluetoothLeAudio; import android.bluetooth.BluetoothLeAudioCodecConfigMetadata; import android.bluetooth.BluetoothLeAudioContentMetadata; @@ -48,8 +48,6 @@ import android.bluetooth.BluetoothLeBroadcastReceiveState; import android.bluetooth.BluetoothLeBroadcastSubgroup; import android.bluetooth.BluetoothProfile; import android.bluetooth.BluetoothStatusCodes; -import android.bluetooth.BluetoothUtils; -import android.bluetooth.BluetoothUtils.TypeValueEntry; import android.bluetooth.BluetoothUuid; import android.bluetooth.IBluetoothLeBroadcastAssistant; import android.bluetooth.IBluetoothLeBroadcastAssistantCallback; @@ -87,7 +85,6 @@ import com.android.bluetooth.le_scan.ScanController; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; -import java.nio.charset.StandardCharsets; import java.time.Duration; import java.util.ArrayDeque; import java.util.ArrayList; @@ -98,6 +95,7 @@ import java.util.Deque; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Optional; @@ -320,33 +318,20 @@ public class BassClientService extends ProfileService { } } - ScanRecord scanRecord = result.getScanRecord(); - if (scanRecord == null) { - Log.w(TAG, "onScanResult: Null scan record"); - return; - } - Map<ParcelUuid, byte[]> listOfUuids = scanRecord.getServiceData(); - if (listOfUuids == null || !listOfUuids.containsKey(BassConstants.BAAS_UUID)) { - Log.d(TAG, "onScanResult: Service data is invalid"); + Integer broadcastId = BassUtils.getBroadcastId(result); + if (broadcastId == BassConstants.INVALID_BROADCAST_ID) { + Log.d(TAG, "onScanResult: Broadcast ID is invalid"); return; } log("Broadcast Source Found:" + result.getDevice()); - byte[] broadcastIdArray = listOfUuids.get(BassConstants.BAAS_UUID); - int broadcastId = BassUtils.parseBroadcastId(broadcastIdArray); - sEventLogger.logd(TAG, "Broadcast Source Found: Broadcast ID: " + broadcastId); - if (broadcastId == BassConstants.INVALID_BROADCAST_ID) { - Log.d(TAG, "onScanResult: Broadcast ID is invalid"); - return; - } - synchronized (mSearchScanCallbackLock) { if (!mCachedBroadcasts.containsKey(broadcastId)) { log("selectBroadcastSource: broadcastId " + broadcastId); mCachedBroadcasts.put(broadcastId, result); - addSelectSourceRequest(broadcastId, false); + addSelectSourceRequest(broadcastId, /* hasPriority= */ false); } else if (mTimeoutHandler.isStarted(broadcastId, MESSAGE_SYNC_LOST_TIMEOUT)) { mTimeoutHandler.stop(broadcastId, MESSAGE_SYNC_LOST_TIMEOUT); mTimeoutHandler.start(broadcastId, MESSAGE_SYNC_LOST_TIMEOUT, sSyncLostTimeout); @@ -628,6 +613,8 @@ public class BassClientService extends ProfileService { if (paResMap == null || (bId != BassConstants.INVALID_BROADCAST_ID && !paResMap.containsKey(bId))) { log("PAResmap: add >>>"); + mSyncHandleToDeviceMap.put(syncHandle, device); + updateSyncHandleForBroadcastId(syncHandle, bId); PeriodicAdvertisementResult paRes = new PeriodicAdvertisementResult( device, @@ -648,7 +635,7 @@ public class BassClientService extends ProfileService { if (bId == BassConstants.INVALID_BROADCAST_ID) { // Update when onSyncEstablished, try to retrieve valid broadcast id if (leaudioBroadcastExtractPeriodicScannerFromStateMachine()) { - bId = getBroadcastIdForSyncHandle(BassConstants.INVALID_SYNC_HANDLE); + bId = getBroadcastIdForSyncHandle(BassConstants.PENDING_SYNC_HANDLE); if (bId == BassConstants.INVALID_BROADCAST_ID || !paResMap.containsKey(bId)) { Log.e(TAG, "PAResmap: error! no valid broadcast id found>>>"); @@ -687,7 +674,11 @@ public class BassClientService extends ProfileService { if (advSid != BassConstants.INVALID_ADV_SID) { paRes.updateAdvSid(advSid); } - if (syncHandle != BassConstants.INVALID_SYNC_HANDLE) { + if (syncHandle != BassConstants.INVALID_SYNC_HANDLE + && syncHandle != BassConstants.PENDING_SYNC_HANDLE) { + mSyncHandleToDeviceMap + .entrySet() + .removeIf(entry -> entry.getValue().equals(device)); mSyncHandleToDeviceMap.put(syncHandle, device); paRes.updateSyncHandle(syncHandle); if (paRes.getBroadcastId() != BassConstants.INVALID_BROADCAST_ID) { @@ -952,8 +943,8 @@ public class BassClientService extends ProfileService { return mSyncHandleToDeviceMap.get(syncHandle); } - int getSyncHandleForBroadcastId(int broadcastId) { - int syncHandle = BassConstants.INVALID_SYNC_HANDLE; + Integer getSyncHandleForBroadcastId(int broadcastId) { + Integer syncHandle = BassConstants.INVALID_SYNC_HANDLE; for (Map.Entry<Integer, Integer> entry : mSyncHandleToBroadcastIdMap.entrySet()) { Integer value = entry.getValue(); if (value == broadcastId) { @@ -964,7 +955,7 @@ public class BassClientService extends ProfileService { return syncHandle; } - int getBroadcastIdForSyncHandle(int syncHandle) { + Integer getBroadcastIdForSyncHandle(int syncHandle) { if (mSyncHandleToBroadcastIdMap.containsKey(syncHandle)) { return mSyncHandleToBroadcastIdMap.get(syncHandle); } @@ -1208,35 +1199,50 @@ public class BassClientService extends ProfileService { synchronized (mSinksWaitingForPast) { mSinksWaitingForPast.put(sink, new Pair<Integer, Integer>(broadcastId, sourceId)); } - addSelectSourceRequest(broadcastId, true); + addSelectSourceRequest(broadcastId, /* hasPriority= */ true); } private void localNotifyReceiveStateChanged( BluetoothDevice sink, BluetoothLeBroadcastReceiveState receiveState) { int broadcastId = receiveState.getBroadcastId(); + // If sink has external broadcast synced && not paused by the host if (leaudioBroadcastResyncHelper() && !isLocalBroadcast(receiveState) && !isEmptyBluetoothDevice(receiveState.getSourceDevice()) && !isHostPauseType(broadcastId)) { + // If sink actively synced (PA or BIG) or waiting for PA if (isReceiverActive(receiveState) || receiveState.getPaSyncState() == BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_SYNCINFO_REQUEST) { + // Clear paused broadcast sink (not need to resume manually) mPausedBroadcastSinks.remove(sink); + + // If all sinks for this broadcast are actively synced (PA or BIG) and there is no + // more sinks to resume then stop monitoring if (isAllReceiversActive(broadcastId) && mPausedBroadcastSinks.isEmpty()) { - stopBigMonitoring(broadcastId, false); + stopBigMonitoring(broadcastId, /* hostInitiated= */ false); } + // If broadcast not paused (monitored) yet } else if (!mPausedBroadcastIds.containsKey(broadcastId)) { + // And BASS has data to start synchronization if (mCachedBroadcasts.containsKey(broadcastId)) { - addSelectSourceRequest(broadcastId, true); + // Try to sync to it and start BIG monitoring mPausedBroadcastIds.put(broadcastId, PauseType.SINK_UNINTENTIONAL); cacheSuspendingSources(broadcastId); - mTimeoutHandler.stop(broadcastId, MESSAGE_BIG_MONITOR_TIMEOUT); mTimeoutHandler.start( broadcastId, MESSAGE_BIG_MONITOR_TIMEOUT, sBigMonitorTimeout); + addSelectSourceRequest(broadcastId, /* hasPriority= */ true); } } + // If paused by host then stop active sync, it could be not stopped, if during previous + // stop there was pending past request + } else if (leaudioMonitorUnicastSourceWhenManagedByBroadcastDelegator() + && isHostPauseType(broadcastId)) { + stopActiveSync(broadcastId); + // If sink unsynced then remove potentially waiting past and check if any broadcast + // monitoring should be stopped for all broadcast Ids } else if (isEmptyBluetoothDevice(receiveState.getSourceDevice())) { synchronized (mSinksWaitingForPast) { mSinksWaitingForPast.remove(sink); @@ -1302,6 +1308,11 @@ public class BassClientService extends ProfileService { } } + private void localNotifySourceAddFailed( + BluetoothDevice sink, BluetoothLeBroadcastMetadata source) { + removeSinkMetadata(sink, source.getBroadcastId()); + } + private void setSourceGroupManaged(BluetoothDevice sink, int sourceId, boolean isGroupOp) { log("setSourceGroupManaged device: " + sink); if (isGroupOp) { @@ -1336,7 +1347,7 @@ public class BassClientService extends ProfileService { if (metadata != null) { int broadcastId = metadata.getBroadcastId(); - for (BluetoothDevice device : getTargetDeviceList(sink, true)) { + for (BluetoothDevice device : getTargetDeviceList(sink, /* isGroupOp= */ true)) { List<BluetoothLeBroadcastReceiveState> sources = getOrCreateStateMachine(device).getAllSources(); @@ -1720,6 +1731,10 @@ public class BassClientService extends ProfileService { synchronized (mSinksWaitingForPast) { mSinksWaitingForPast.remove(device); } + synchronized (mPendingSourcesToAdd) { + mPendingSourcesToAdd.removeIf( + pendingSourcesToAdd -> pendingSourcesToAdd.mSink.equals(device)); + } int bondState = mAdapterService.getBondState(device); if (bondState == BluetoothDevice.BOND_NONE) { @@ -1728,10 +1743,12 @@ public class BassClientService extends ProfileService { } checkAndStopBigMonitoring(); + removeSinkMetadataFromGroupIfWholeUnsynced(device); if (getConnectedDevices().isEmpty() || (mPausedBroadcastSinks.isEmpty() && mSinksWaitingForPast.isEmpty() + && mPendingSourcesToAdd.isEmpty() && !isAnyConnectedDeviceSwitchingSource())) { synchronized (mSearchScanCallbackLock) { // when searching is stopped then clear all sync data @@ -2048,41 +2065,23 @@ public class BassClientService extends ProfileService { Log.e(TAG, "LE Scan has already started"); return; } - ScanRecord scanRecord = result.getScanRecord(); - if (scanRecord == null) { - Log.e(TAG, "Null scan record"); - return; - } - Map<ParcelUuid, byte[]> listOfUuids = - scanRecord.getServiceData(); - if (listOfUuids == null) { - Log.e(TAG, "Service data is null"); - return; - } - if (!listOfUuids.containsKey(BassConstants.BAAS_UUID)) { + Integer broadcastId = BassUtils.getBroadcastId(result); + if (broadcastId == BassConstants.INVALID_BROADCAST_ID) { + Log.d(TAG, "onScanResult: Broadcast ID is invalid"); return; } - log("Broadcast Source Found:" + result.getDevice()); - byte[] broadcastIdArray = - listOfUuids.get(BassConstants.BAAS_UUID); - int broadcastId = - (int) - (((broadcastIdArray[2] & 0xff) << 16) - | ((broadcastIdArray[1] & 0xff) << 8) - | (broadcastIdArray[0] & 0xff)); + log("Broadcast Source Found:" + result.getDevice()); sEventLogger.logd( TAG, "Broadcast Source Found: Broadcast ID: " + broadcastId); - if (broadcastId == BassConstants.INVALID_BROADCAST_ID) { - return; - } if (!mCachedBroadcasts.containsKey(broadcastId)) { log("selectBroadcastSource: broadcastId " + broadcastId); mCachedBroadcasts.put(broadcastId, result); if (leaudioBroadcastExtractPeriodicScannerFromStateMachine()) { - addSelectSourceRequest(broadcastId, false); + addSelectSourceRequest( + broadcastId, /* hasPriority= */ false); } else { synchronized (mStateMachines) { for (BassClientStateMachine sm : @@ -2115,25 +2114,63 @@ public class BassClientService extends ProfileService { mSyncFailureCounter.clear(); mHandler.removeMessages(MESSAGE_SYNC_TIMEOUT); if (leaudioBroadcastResyncHelper()) { - // Sync to the broadcasts already synced with sinks - Set<Integer> syncedBroadcasts = getExternalBroadcastsActiveOnSinks(); - for (int syncedBroadcast : syncedBroadcasts) { - addSelectSourceRequest(syncedBroadcast, true); + if (leaudioBroadcastPreventResumeInterruption()) { + // Collect broadcasts which should be sync and/or cache should remain. + // Broadcasts, which has to be synced, needs to have cache available. + // Broadcasts which only cache should remain (i.e. because of potential resume) + // has to be synced too to show it on the list before resume. + LinkedHashSet<Integer> broadcastsToSync = new LinkedHashSet<>(); + + // Keep already synced broadcasts + broadcastsToSync.addAll(getBroadcastIdsOfSyncedBroadcasters()); + + // Sync to the broadcasts already synced with sinks + broadcastsToSync.addAll(getExternalBroadcastsActiveOnSinks()); + + // Sync to the broadcasts waiting for PAST + broadcastsToSync.addAll(getBroadcastIdsWaitingForPAST()); + + // Sync to the broadcasts waiting for adding source (could be by resume too). + broadcastsToSync.addAll(getBroadcastIdsWaitingForAddSource()); + + // Sync to the paused broadcasts (INTENTIONAL and UNINTENTIONAL) based on the + // mPausedBroadcastSinks as mPausedBroadcastIds could be already removed by + // resume execution + broadcastsToSync.addAll(getPausedBroadcastIdsBasedOnSinks()); + + log("Broadcasts to sync on start: " + broadcastsToSync); + + // Add broadcsts to sync queue + for (int broadcastId : broadcastsToSync) { + addSelectSourceRequest(broadcastId, /* hasPriority= */ true); + } + + // When starting scan, clear the previously cached broadcast scan results, + // skip broadcast already added to sync + mCachedBroadcasts.keySet().removeIf(key -> !broadcastsToSync.contains(key)); + + printAllSyncData(); + } else { + // Sync to the broadcasts already synced with sinks + Set<Integer> syncedBroadcasts = getExternalBroadcastsActiveOnSinks(); + for (int syncedBroadcast : syncedBroadcasts) { + addSelectSourceRequest(syncedBroadcast, /* hasPriority= */ true); + } + // when starting scan, clear the previously cached broadcast scan results + mCachedBroadcasts + .keySet() + .removeIf( + key -> + !mPausedBroadcastIds.containsKey(key) + || !mPausedBroadcastIds + .get(key) + .equals(PauseType.SINK_UNINTENTIONAL)); } - // when starting scan, clear the previously cached broadcast scan results - mCachedBroadcasts - .keySet() - .removeIf( - key -> - !mPausedBroadcastIds.containsKey(key) - || !mPausedBroadcastIds - .get(key) - .equals(PauseType.SINK_UNINTENTIONAL)); } else { - // when starting scan, clear the previously cached broadcast scan results + // When starting scan, clear the previously cached broadcast scan results mCachedBroadcasts.clear(); } - // clear previous sources notify flag before scanning new result + // Clear previous sources notify flag before scanning new result // this is to make sure the active sources are notified even if already synced clearNotifiedFlags(); @@ -2231,37 +2268,114 @@ public class BassClientService extends ProfileService { mBluetoothLeScannerWrapper = null; mSearchScanCallback = null; } - clearAllSyncData(); + + if (leaudioBroadcastPreventResumeInterruption()) { + printAllSyncData(); + + // Collect broadcasts which should stay synced after search stops + HashSet<Integer> broadcastsToKeepSynced = new HashSet<>(); + + // Keep broadcasts waiting for PAST + broadcastsToKeepSynced.addAll(getBroadcastIdsWaitingForPAST()); + + // Keep broadcasts waiting for adding source (could be by resume too) + broadcastsToKeepSynced.addAll(getBroadcastIdsWaitingForAddSource()); + + // Keep broadcast UNINTENTIONALly paused + broadcastsToKeepSynced.addAll(getUnintentionallyPausedBroadcastIds()); + + log("Broadcasts to keep on stop: " + broadcastsToKeepSynced); + + // Remove all other broadcasts from sync queue if not in broadcastsToKeepSynced + synchronized (mSourceSyncRequestsQueue) { + Iterator<SourceSyncRequest> iterator = mSourceSyncRequestsQueue.iterator(); + while (iterator.hasNext()) { + SourceSyncRequest sourceSyncRequest = iterator.next(); + Integer queuedBroadcastId = + BassUtils.getBroadcastId(sourceSyncRequest.getScanResult()); + if (!broadcastsToKeepSynced.contains(queuedBroadcastId)) { + iterator.remove(); + } + } + } + + // Collect broadcasts (sync handles) which should be unsynced (not in keep list) + List<Integer> syncHandlesToRemove = + new ArrayList<>(mSyncHandleToBroadcastIdMap.keySet()); + for (int broadcastId : broadcastsToKeepSynced) { + syncHandlesToRemove.remove(getSyncHandleForBroadcastId(broadcastId)); + } + + // Unsync not needed broadcasts + for (int syncHandleToRemove : syncHandlesToRemove) { + cancelActiveSync(syncHandleToRemove); + } + + mSyncFailureCounter.clear(); + + printAllSyncData(); + } else { + clearAllSyncData(); + } + informConnectedDeviceAboutScanOffloadStop(); sEventLogger.logd(TAG, "stopSearchingForSources"); mCallbacks.notifySearchStopped(BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST); - for (Map.Entry<Integer, PauseType> entry : mPausedBroadcastIds.entrySet()) { - Integer broadcastId = entry.getKey(); - PauseType pauseType = entry.getValue(); - if (pauseType != PauseType.HOST_INTENTIONAL) { - addSelectSourceRequest(broadcastId, true); + + if (!leaudioBroadcastPreventResumeInterruption()) { + for (Map.Entry<Integer, PauseType> entry : mPausedBroadcastIds.entrySet()) { + Integer broadcastId = entry.getKey(); + PauseType pauseType = entry.getValue(); + if (pauseType != PauseType.HOST_INTENTIONAL) { + addSelectSourceRequest(broadcastId, /* hasPriority= */ true); + } } } } } } + private void printAllSyncData() { + Log.v( + TAG, + "printAllSyncData" + + ("\n mActiveSyncedSources: " + mActiveSyncedSources) + + ("\n mPeriodicAdvCallbacksMap: " + mPeriodicAdvCallbacksMap) + + ("\n mSyncHandleToBaseDataMap: " + mSyncHandleToBaseDataMap) + + ("\n mBisDiscoveryCounterMap: " + mBisDiscoveryCounterMap) + + ("\n mSyncHandleToDeviceMap: " + mSyncHandleToDeviceMap) + + ("\n mSyncHandleToBroadcastIdMap: " + mSyncHandleToBroadcastIdMap) + + ("\n mPeriodicAdvertisementResultMap: " + mPeriodicAdvertisementResultMap) + + ("\n mSourceSyncRequestsQueue: " + mSourceSyncRequestsQueue) + + ("\n mSyncFailureCounter: " + mSyncFailureCounter) + + ("\n mPendingSourcesToAdd: " + mPendingSourcesToAdd) + + ("\n mSinksWaitingForPast: " + mSinksWaitingForPast) + + ("\n mPausedBroadcastIds: " + mPausedBroadcastIds) + + ("\n mPausedBroadcastSinks: " + mPausedBroadcastSinks) + + ("\n mCachedBroadcasts: " + mCachedBroadcasts) + + ("\n mBroadcastMetadataMap: " + mBroadcastMetadataMap)); + } + private void clearAllSyncData() { log("clearAllSyncData"); - mTimeoutHandler.stopAll(MESSAGE_SYNC_LOST_TIMEOUT); - mSourceSyncRequestsQueue.clear(); - mSyncFailureCounter.clear(); - mPendingSourcesToAdd.clear(); + synchronized (mSourceSyncRequestsQueue) { + mTimeoutHandler.stopAll(MESSAGE_SYNC_LOST_TIMEOUT); + mSourceSyncRequestsQueue.clear(); + mSyncFailureCounter.clear(); + if (!leaudioBroadcastPreventResumeInterruption()) { + mPendingSourcesToAdd.clear(); + } - cancelActiveSync(null); - mActiveSyncedSources.clear(); - mPeriodicAdvCallbacksMap.clear(); - mBisDiscoveryCounterMap.clear(); + cancelActiveSync(null); + mActiveSyncedSources.clear(); + mPeriodicAdvCallbacksMap.clear(); + mBisDiscoveryCounterMap.clear(); - mSyncHandleToDeviceMap.clear(); - mSyncHandleToBaseDataMap.clear(); - mSyncHandleToBroadcastIdMap.clear(); - mPeriodicAdvertisementResultMap.clear(); + mSyncHandleToDeviceMap.clear(); + mSyncHandleToBaseDataMap.clear(); + mSyncHandleToBroadcastIdMap.clear(); + mPeriodicAdvertisementResultMap.clear(); + } } /** @@ -2289,7 +2403,7 @@ public class BassClientService extends ProfileService { int skip, int timeout, int status) { - int broadcastId = getBroadcastIdForSyncHandle(BassConstants.INVALID_SYNC_HANDLE); + int broadcastId = getBroadcastIdForSyncHandle(BassConstants.PENDING_SYNC_HANDLE); log( "onSyncEstablished syncHandle: " + syncHandle @@ -2305,95 +2419,15 @@ public class BassClientService extends ProfileService { + timeout + ", status: " + status); - if (status == BluetoothGatt.GATT_SUCCESS) { - // updates syncHandle, advSid - // set other fields as invalid or null - updatePeriodicAdvertisementResultMap( - device, - BassConstants.INVALID_ADV_ADDRESS_TYPE, - syncHandle, - advertisingSid, - BassConstants.INVALID_ADV_INTERVAL, - BassConstants.INVALID_BROADCAST_ID, - null, - null); - addActiveSyncedSource(syncHandle); - if (!leaudioBroadcastResyncHelper()) { - synchronized (mSearchScanCallbackLock) { - // when searching is stopped then start timer to stop active syncs - if (!isSearchInProgress()) { - mHandler.removeMessages(MESSAGE_SYNC_TIMEOUT); - log("Started MESSAGE_SYNC_TIMEOUT"); - mHandler.sendEmptyMessageDelayed( - MESSAGE_SYNC_TIMEOUT, sSyncActiveTimeout.toMillis()); - } - } - } else { - mTimeoutHandler.stop(broadcastId, MESSAGE_BROADCAST_MONITOR_TIMEOUT); - } - - // update valid sync handle in mPeriodicAdvCallbacksMap - synchronized (mPeriodicAdvCallbacksMap) { - if (mPeriodicAdvCallbacksMap.containsKey(BassConstants.INVALID_SYNC_HANDLE)) { - PeriodicAdvertisingCallback paCb = - mPeriodicAdvCallbacksMap.get(BassConstants.INVALID_SYNC_HANDLE); - mPeriodicAdvCallbacksMap.put(syncHandle, paCb); - mPeriodicAdvCallbacksMap.remove(BassConstants.INVALID_SYNC_HANDLE); - } - } - mBisDiscoveryCounterMap.put(syncHandle, MAX_BIS_DISCOVERY_TRIES_NUM); - - synchronized (mSinksWaitingForPast) { - Iterator<Map.Entry<BluetoothDevice, Pair<Integer, Integer>>> iterator = - mSinksWaitingForPast.entrySet().iterator(); - while (iterator.hasNext()) { - Map.Entry<BluetoothDevice, Pair<Integer, Integer>> entry = iterator.next(); - BluetoothDevice sinkDevice = entry.getKey(); - int broadcastIdForPast = entry.getValue().first; - if (broadcastId == broadcastIdForPast) { - int sourceId = entry.getValue().second; - synchronized (mStateMachines) { - BassClientStateMachine sm = getOrCreateStateMachine(sinkDevice); - Message message = - sm.obtainMessage( - BassClientStateMachine.INITIATE_PA_SYNC_TRANSFER); - message.arg1 = syncHandle; - message.arg2 = sourceId; - sm.sendMessage(message); - } - synchronized (mPendingSourcesToAdd) { - Iterator<AddSourceData> addIterator = - mPendingSourcesToAdd.iterator(); - while (addIterator.hasNext()) { - AddSourceData pendingSourcesToAdd = addIterator.next(); - if (pendingSourcesToAdd.mSourceMetadata.getBroadcastId() - == broadcastId - && pendingSourcesToAdd.mSink.equals(sinkDevice)) { - addIterator.remove(); - } - } - } - iterator.remove(); - } - } - } + if (broadcastId == BassConstants.INVALID_BROADCAST_ID) { + Log.w(TAG, "onSyncEstablished unexpected call, no pending synchronization"); + handleSelectSourceRequest(); + return; + } - synchronized (mPendingSourcesToAdd) { - Iterator<AddSourceData> iterator = mPendingSourcesToAdd.iterator(); - while (iterator.hasNext()) { - AddSourceData pendingSourcesToAdd = iterator.next(); - if (pendingSourcesToAdd.mSourceMetadata.getBroadcastId() == broadcastId) { - addSource( - pendingSourcesToAdd.mSink, - pendingSourcesToAdd.mSourceMetadata, - pendingSourcesToAdd.mIsGroupOp); - iterator.remove(); - } - } - } - } else { - // remove failed sync handle + final int ERROR_CODE_SUCCESS = 0x00; + if (status != ERROR_CODE_SUCCESS) { log("onSyncEstablished failed for broadcast id: " + broadcastId); boolean notifiedOfLost = false; synchronized (mPendingSourcesToAdd) { @@ -2425,7 +2459,7 @@ public class BassClientService extends ProfileService { MESSAGE_BROADCAST_MONITOR_TIMEOUT, sBroadcasterMonitorTimeout); } - addSelectSourceRequest(broadcastId, true); + addSelectSourceRequest(broadcastId, /* hasPriority= */ true); } else { // Clear from cache to make possible sync again (only during active searching) synchronized (mSearchScanCallbackLock) { @@ -2434,7 +2468,112 @@ public class BassClientService extends ProfileService { } } } - mPeriodicAdvCallbacksMap.remove(BassConstants.INVALID_SYNC_HANDLE); + clearAllDataForSyncHandle(BassConstants.PENDING_SYNC_HANDLE); + handleSelectSourceRequest(); + return; + } + + synchronized (mSourceSyncRequestsQueue) { + // updates syncHandle, advSid + // set other fields as invalid or null + updatePeriodicAdvertisementResultMap( + device, + BassConstants.INVALID_ADV_ADDRESS_TYPE, + syncHandle, + advertisingSid, + BassConstants.INVALID_ADV_INTERVAL, + BassConstants.INVALID_BROADCAST_ID, + null, + null); + addActiveSyncedSource(syncHandle); + + if (!leaudioBroadcastResyncHelper()) { + synchronized (mSearchScanCallbackLock) { + // when searching is stopped then start timer to stop active syncs + if (!isSearchInProgress()) { + mHandler.removeMessages(MESSAGE_SYNC_TIMEOUT); + log("Started MESSAGE_SYNC_TIMEOUT"); + mHandler.sendEmptyMessageDelayed( + MESSAGE_SYNC_TIMEOUT, sSyncActiveTimeout.toMillis()); + } + } + } else { + mTimeoutHandler.stop(broadcastId, MESSAGE_BROADCAST_MONITOR_TIMEOUT); + } + + // update valid sync handle in mPeriodicAdvCallbacksMap + if (mPeriodicAdvCallbacksMap.containsKey(BassConstants.PENDING_SYNC_HANDLE)) { + PeriodicAdvertisingCallback paCb = + mPeriodicAdvCallbacksMap.get(BassConstants.PENDING_SYNC_HANDLE); + mPeriodicAdvCallbacksMap.put(syncHandle, paCb); + mPeriodicAdvCallbacksMap.remove(BassConstants.PENDING_SYNC_HANDLE); + } + + mBisDiscoveryCounterMap.put(syncHandle, MAX_BIS_DISCOVERY_TRIES_NUM); + } + synchronized (mSinksWaitingForPast) { + Iterator<Map.Entry<BluetoothDevice, Pair<Integer, Integer>>> iterator = + mSinksWaitingForPast.entrySet().iterator(); + while (iterator.hasNext()) { + Map.Entry<BluetoothDevice, Pair<Integer, Integer>> entry = iterator.next(); + BluetoothDevice sinkDevice = entry.getKey(); + int broadcastIdForPast = entry.getValue().first; + if (broadcastId == broadcastIdForPast) { + int sourceId = entry.getValue().second; + synchronized (mStateMachines) { + BassClientStateMachine sm = getOrCreateStateMachine(sinkDevice); + Message message = + sm.obtainMessage( + BassClientStateMachine.INITIATE_PA_SYNC_TRANSFER); + message.arg1 = syncHandle; + message.arg2 = sourceId; + sm.sendMessage(message); + } + synchronized (mPendingSourcesToAdd) { + Iterator<AddSourceData> addIterator = mPendingSourcesToAdd.iterator(); + while (addIterator.hasNext()) { + AddSourceData pendingSourcesToAdd = addIterator.next(); + if (pendingSourcesToAdd.mSourceMetadata.getBroadcastId() + == broadcastId + && pendingSourcesToAdd.mSink.equals(sinkDevice)) { + addIterator.remove(); + } + } + } + iterator.remove(); + } + } + } + synchronized (mPendingSourcesToAdd) { + List<AddSourceData> pendingSourcesToAdd = new ArrayList<>(); + Iterator<AddSourceData> iterator = mPendingSourcesToAdd.iterator(); + while (iterator.hasNext()) { + AddSourceData pendingSourceToAdd = iterator.next(); + if (pendingSourceToAdd.mSourceMetadata.getBroadcastId() == broadcastId) { + boolean addSource = true; + if (pendingSourceToAdd.mIsGroupOp && !pendingSourcesToAdd.isEmpty()) { + List<BluetoothDevice> deviceGroup = + getTargetDeviceList( + pendingSourceToAdd.mSink, /* isGroupOp= */ true); + for (AddSourceData addSourceData : pendingSourcesToAdd) { + if (addSourceData.mIsGroupOp + && deviceGroup.contains(addSourceData.mSink)) { + addSource = false; + } + } + } + if (addSource) { + pendingSourcesToAdd.add(pendingSourceToAdd); + } + iterator.remove(); + } + } + for (AddSourceData addSourceData : pendingSourcesToAdd) { + addSource( + addSourceData.mSink, + addSourceData.mSourceMetadata, + addSourceData.mIsGroupOp); + } } handleSelectSourceRequest(); } @@ -2511,7 +2650,7 @@ public class BassClientService extends ProfileService { MESSAGE_BROADCAST_MONITOR_TIMEOUT, sBroadcasterMonitorTimeout); } - addSelectSourceRequest(broadcastId, true); + addSelectSourceRequest(broadcastId, /* hasPriority= */ true); } else { if (leaudioBroadcastResyncHelper()) { mTimeoutHandler.start( @@ -2575,42 +2714,33 @@ public class BassClientService extends ProfileService { } private void clearAllDataForSyncHandle(Integer syncHandle) { - removeActiveSyncedSource(syncHandle); - mPeriodicAdvCallbacksMap.remove(syncHandle); - mSyncHandleToBaseDataMap.remove(syncHandle); - mBisDiscoveryCounterMap.remove(syncHandle); - BluetoothDevice srcDevice = getDeviceForSyncHandle(syncHandle); - mSyncHandleToDeviceMap.remove(syncHandle); - int broadcastId = getBroadcastIdForSyncHandle(syncHandle); - if (leaudioMonitorUnicastSourceWhenManagedByBroadcastDelegator()) { + synchronized (mSourceSyncRequestsQueue) { + removeActiveSyncedSource(syncHandle); + mPeriodicAdvCallbacksMap.remove(syncHandle); + mSyncHandleToBaseDataMap.remove(syncHandle); + mBisDiscoveryCounterMap.remove(syncHandle); + BluetoothDevice srcDevice = getDeviceForSyncHandle(syncHandle); + mSyncHandleToDeviceMap.remove(syncHandle); + int broadcastId = getBroadcastIdForSyncHandle(syncHandle); synchronized (mPendingSourcesToAdd) { - Iterator<AddSourceData> iterator = mPendingSourcesToAdd.iterator(); - while (iterator.hasNext()) { - AddSourceData pendingSourcesToAdd = iterator.next(); - if (pendingSourcesToAdd.mSourceMetadata.getBroadcastId() == broadcastId) { - iterator.remove(); - } - } + mPendingSourcesToAdd.removeIf( + pendingSourcesToAdd -> + pendingSourcesToAdd.mSourceMetadata.getBroadcastId() + == broadcastId); } synchronized (mSinksWaitingForPast) { - Iterator<Map.Entry<BluetoothDevice, Pair<Integer, Integer>>> iterator = - mSinksWaitingForPast.entrySet().iterator(); - while (iterator.hasNext()) { - Map.Entry<BluetoothDevice, Pair<Integer, Integer>> entry = iterator.next(); - int broadcastIdForPast = entry.getValue().first; - if (broadcastId == broadcastIdForPast) { - iterator.remove(); - } + mSinksWaitingForPast + .entrySet() + .removeIf(entry -> entry.getValue().first == broadcastId); + } + mSyncHandleToBroadcastIdMap.remove(syncHandle); + if (srcDevice != null) { + mPeriodicAdvertisementResultMap.get(srcDevice).remove(broadcastId); + if (mPeriodicAdvertisementResultMap.get(srcDevice).isEmpty()) { + mPeriodicAdvertisementResultMap.remove(srcDevice); } } } - mSyncHandleToBroadcastIdMap.remove(syncHandle); - if (srcDevice != null) { - mPeriodicAdvertisementResultMap.get(srcDevice).remove(broadcastId); - if (mPeriodicAdvertisementResultMap.get(srcDevice).isEmpty()) { - mPeriodicAdvertisementResultMap.remove(srcDevice); - } - } } private BluetoothLeBroadcastMetadata getBroadcastMetadataFromBaseData( @@ -2711,13 +2841,17 @@ public class BassClientService extends ProfileService { return metaData.build(); } + /** + * @param syncHandle syncHandle to unsync source and clean up all data for it. Null is used to + * clean up all pending and established broadcast syncs. + */ private void cancelActiveSync(Integer syncHandle) { log("cancelActiveSync: syncHandle = " + syncHandle); if (syncHandle == null || (leaudioBroadcastResyncHelper() - && syncHandle == BassConstants.INVALID_SYNC_HANDLE)) { - // clean up the pending sync request if syncHandle is null - unsyncSource(BassConstants.INVALID_SYNC_HANDLE); + && syncHandle == BassConstants.PENDING_SYNC_HANDLE)) { + // cancel the pending sync request + unsyncSource(BassConstants.PENDING_SYNC_HANDLE); } List<Integer> activeSyncedSrc = new ArrayList<>(getActiveSyncedSources()); @@ -2728,12 +2862,13 @@ public class BassClientService extends ProfileService { // only one source needs to be unsynced unsyncSource(syncHandle); } else { - // remove all the sources + // unsync all the sources for (int handle : activeSyncedSrc) { unsyncSource(handle); } } } + printAllSyncData(); } @SuppressLint("AndroidFrameworkRequiresPermission") // TODO: b/350563786 - Fix BASS annotation @@ -2747,7 +2882,7 @@ public class BassClientService extends ProfileService { .getPeriodicAdvertisingManager(), mPeriodicAdvCallbacksMap.get(syncHandle)); } catch (IllegalArgumentException ex) { - Log.w(TAG, "unregisterSync:IllegalArgumentException"); + Log.e(TAG, "unregisterSync:IllegalArgumentException"); return false; } } else { @@ -2798,32 +2933,6 @@ public class BassClientService extends ProfileService { return false; } - private String checkAndParseBroadcastName(ScanRecord record) { - log("checkAndParseBroadcastName"); - byte[] rawBytes = record.getBytes(); - List<TypeValueEntry> entries = BluetoothUtils.parseLengthTypeValueBytes(rawBytes); - if (rawBytes.length > 0 && rawBytes[0] > 0 && entries.isEmpty()) { - Log.e(TAG, "Invalid LTV entries in Scan record"); - return null; - } - - String broadcastName = null; - for (TypeValueEntry entry : entries) { - // Only use the first value of each type - if (broadcastName == null && entry.getType() == BassConstants.BCAST_NAME_AD_TYPE) { - byte[] bytes = entry.getValue(); - int len = bytes.length; - if (len < BassConstants.BCAST_NAME_LEN_MIN - || len > BassConstants.BCAST_NAME_LEN_MAX) { - Log.e(TAG, "Invalid broadcast name length in Scan record" + len); - return null; - } - broadcastName = new String(bytes, StandardCharsets.UTF_8); - } - } - return broadcastName; - } - void addSelectSourceRequest(int broadcastId, boolean hasPriority) { sEventLogger.logd( TAG, @@ -2858,60 +2967,54 @@ public class BassClientService extends ProfileService { @SuppressLint("AndroidFrameworkRequiresPermission") // TODO: b/350563786 - Fix BASS annotation private void handleSelectSourceRequest() { PeriodicAdvertisingCallback paCb; - synchronized (mPeriodicAdvCallbacksMap) { + ScanResult scanRes; + int broadcastId = BassConstants.INVALID_BROADCAST_ID; + PublicBroadcastData pbData = null; + List<Integer> activeSyncedSrc; + String broadcastName; + + synchronized (mSourceSyncRequestsQueue) { if (mSourceSyncRequestsQueue.isEmpty()) { return; - } else if (mPeriodicAdvCallbacksMap.containsKey(BassConstants.INVALID_SYNC_HANDLE)) { + } else if (mPeriodicAdvCallbacksMap.containsKey(BassConstants.PENDING_SYNC_HANDLE)) { log("handleSelectSourceRequest: already pending sync"); return; - } else { - paCb = new PACallback(); - // put INVALID_SYNC_HANDLE and update in onSyncEstablished - mPeriodicAdvCallbacksMap.put(BassConstants.INVALID_SYNC_HANDLE, paCb); } - } - ScanResult scanRes; - synchronized (mSourceSyncRequestsQueue) { + scanRes = mSourceSyncRequestsQueue.poll().getScanResult(); - } - ScanRecord scanRecord = scanRes.getScanRecord(); + ScanRecord scanRecord = scanRes.getScanRecord(); - sEventLogger.logd(TAG, "Select Broadcast Source, result: " + scanRes); + sEventLogger.logd(TAG, "Select Broadcast Source, result: " + scanRes); - // updating mainly for Address type and PA Interval here - // extract BroadcastId from ScanResult - Map<ParcelUuid, byte[]> listOfUuids = scanRecord.getServiceData(); - int broadcastId = BassConstants.INVALID_BROADCAST_ID; - PublicBroadcastData pbData = null; - if (listOfUuids != null) { - if (listOfUuids.containsKey(BassConstants.BAAS_UUID)) { - byte[] bId = listOfUuids.get(BassConstants.BAAS_UUID); - broadcastId = BassUtils.parseBroadcastId(bId); - } - if (listOfUuids.containsKey(BassConstants.PUBLIC_BROADCAST_UUID)) { - byte[] pbAnnouncement = listOfUuids.get(BassConstants.PUBLIC_BROADCAST_UUID); - pbData = PublicBroadcastData.parsePublicBroadcastData(pbAnnouncement); + broadcastId = BassUtils.getBroadcastId(scanRecord); + if (broadcastId == BassConstants.INVALID_BROADCAST_ID) { + Log.e(TAG, "Invalid broadcast ID"); + handleSelectSourceRequest(); + return; } - } - if (broadcastId == BassConstants.INVALID_BROADCAST_ID) { - Log.w(TAG, "Invalid broadcast ID"); - mPeriodicAdvCallbacksMap.remove(BassConstants.INVALID_SYNC_HANDLE); - handleSelectSourceRequest(); - return; - } - - // Check if broadcast name present in scan record and parse - // null if no name present - String broadcastName = checkAndParseBroadcastName(scanRecord); + // Avoid duplicated sync request if the same broadcast BIG is synced + activeSyncedSrc = new ArrayList<>(getActiveSyncedSources()); + if (activeSyncedSrc.contains(getSyncHandleForBroadcastId(broadcastId))) { + log("Skip duplicated sync request to broadcast id: " + broadcastId); + handleSelectSourceRequest(); + return; + } - // Avoid duplicated sync request if the same broadcast BIG is synced - List<Integer> activeSyncedSrc = new ArrayList<>(getActiveSyncedSources()); - if (activeSyncedSrc.contains(getSyncHandleForBroadcastId(broadcastId))) { - log("Skip duplicated sync request to broadcast id: " + broadcastId); - mPeriodicAdvCallbacksMap.remove(BassConstants.INVALID_SYNC_HANDLE); - handleSelectSourceRequest(); - return; + pbData = BassUtils.getPublicBroadcastData(scanRecord); + broadcastName = BassUtils.getBroadcastName(scanRecord); + paCb = new PACallback(); + // put PENDING_SYNC_HANDLE and update it in onSyncEstablished + mPeriodicAdvCallbacksMap.put(BassConstants.PENDING_SYNC_HANDLE, paCb); + updatePeriodicAdvertisementResultMap( + scanRes.getDevice(), + scanRes.getDevice().getAddressType(), + BassConstants.PENDING_SYNC_HANDLE, + BassConstants.INVALID_ADV_SID, + scanRes.getPeriodicAdvertisingInterval(), + broadcastId, + pbData, + broadcastName); } // Check if there are resources for sync @@ -2953,22 +3056,11 @@ public class BassClientService extends ProfileService { paCb, null); } catch (IllegalArgumentException ex) { - Log.w(TAG, "registerSync:IllegalArgumentException"); - mPeriodicAdvCallbacksMap.remove(BassConstants.INVALID_SYNC_HANDLE); + Log.e(TAG, "registerSync:IllegalArgumentException"); + clearAllDataForSyncHandle(BassConstants.PENDING_SYNC_HANDLE); handleSelectSourceRequest(); return; } - - updateSyncHandleForBroadcastId(BassConstants.INVALID_SYNC_HANDLE, broadcastId); - updatePeriodicAdvertisementResultMap( - scanRes.getDevice(), - scanRes.getDevice().getAddressType(), - BassConstants.INVALID_SYNC_HANDLE, - BassConstants.INVALID_ADV_SID, - scanRes.getPeriodicAdvertisingInterval(), - broadcastId, - pbData, - broadcastName); } void selectSource(BluetoothDevice sink, ScanResult result, boolean autoTrigger) { @@ -3040,18 +3132,7 @@ public class BassClientService extends ProfileService { }); } - private void removeSinkMetadata(BluetoothDevice device, int broadcastId) { - if (device == null || broadcastId == BassConstants.INVALID_BROADCAST_ID) { - Log.e( - TAG, - "Failed to remove Sink Metadata, invalid parameters (device: " - + device - + ", broadcastId: " - + broadcastId - + ")"); - return; - } - + private void removeSinkMetadataHelper(BluetoothDevice device, int broadcastId) { mBroadcastMetadataMap.compute( device, (key, existingMap) -> { @@ -3061,7 +3142,7 @@ public class BassClientService extends ProfileService { return null; } } else { - Log.w( + Log.d( TAG, "There is no metadata related to sink (device: " + device @@ -3072,6 +3153,22 @@ public class BassClientService extends ProfileService { }); } + private void removeSinkMetadata(BluetoothDevice device, int broadcastId) { + if (device == null || broadcastId == BassConstants.INVALID_BROADCAST_ID) { + Log.e( + TAG, + "Failed to remove Sink Metadata, invalid parameters (device: " + + device + + ", broadcastId: " + + broadcastId + + ")"); + return; + } + + removeSinkMetadataHelper(device, broadcastId); + removeSinkMetadataFromGroupIfWholeUnsynced(device, broadcastId); + } + private void removeSinkMetadata(BluetoothDevice device) { if (device == null) { Log.e( @@ -3081,6 +3178,125 @@ public class BassClientService extends ProfileService { } mBroadcastMetadataMap.remove(device); + removeSinkMetadataFromGroupIfWholeUnsynced(device); + } + + /** + * Removes sink metadata from a group if all other sinks (except the given device) are unsynced + * from the given broadcast and not paused by the host. If this condition is met, sink metadata + * is removed from the entire group, including the given device. + * + * @param device The Bluetooth device for which group synchronization with the broadcast should + * be checked. The given device is skipped in the check because even if its sink metadata + * has been removed, it may still be synchronized with the broadcast. + * @param broadcastId The broadcast ID to check against. + */ + private void removeSinkMetadataFromGroupIfWholeUnsynced( + BluetoothDevice device, int broadcastId) { + if (device == null || broadcastId == BassConstants.INVALID_BROADCAST_ID) { + Log.e( + TAG, + "Failed to remove Sink Metadata, invalid parameters (device: " + + device + + ", broadcastId: " + + broadcastId + + ")"); + return; + } + + List<BluetoothDevice> sinks = getTargetDeviceList(device, /* isGroupOp= */ true); + boolean removeSinks = true; + // Check if all others sinks than this device are unsynced and not paused by host + // This device is removed or should be removed, so it has to be skipped in that check + for (BluetoothDevice sink : sinks) { + if (sink.equals(device)) { + continue; + } + if (getAllSources(sink).stream().anyMatch(rs -> (rs.getBroadcastId() == broadcastId)) + || (isHostPauseType(broadcastId) && !mPausedBroadcastSinks.isEmpty())) { + removeSinks = false; + break; + } + } + // Then remove such metadata from all of them + if (removeSinks) { + for (BluetoothDevice sink : sinks) { + removeSinkMetadataHelper(sink, broadcastId); + } + } + } + + /** + * Removes sink metadata from a group if all other sinks (except the given device) are unsynced + * from any broadcast and not paused by the host. If this condition is met, sink metadata is + * removed from the entire group, including the given device. + * + * @param device The Bluetooth device for which group synchronization with the broadcasts should + * be checked. The given device is skipped in the check because even if its sink metadata + * has been removed, it may still be synchronized with the broadcast. + */ + private void removeSinkMetadataFromGroupIfWholeUnsynced(BluetoothDevice device) { + if (device == null) { + Log.e( + TAG, + "Failed to remove Sink Metadata, invalid parameter (device: " + device + ")"); + return; + } + + List<BluetoothDevice> sinks = getTargetDeviceList(device, /* isGroupOp= */ true); + // Check sync for broadcastIds from all sinks in group as device could be already removed + for (BluetoothDevice sink : sinks) { + List<Integer> broadcastIds = + new ArrayList<>( + mBroadcastMetadataMap + .getOrDefault(sink, Collections.emptyMap()) + .keySet()); + // Check all broadcastIds sync for each sink and remove metadata if group unsynced + for (Integer broadcastId : broadcastIds) { + // The device is used intentionally instead of a sink, even if we use broadcastIds + // from other sinks + removeSinkMetadataFromGroupIfWholeUnsynced(device, broadcastId); + } + } + } + + private void checkIfBroadcastIsSuspendedBySourceRemovalAndClearData( + BluetoothDevice device, BassClientStateMachine stateMachine) { + if (!mPausedBroadcastSinks.contains(device)) { + return; + } + Map<Integer, BluetoothLeBroadcastMetadata> entry = mBroadcastMetadataMap.get(device); + if (entry == null) { + return; + } + if (entry.keySet().size() >= stateMachine.getMaximumSourceCapacity()) { + for (Integer broadcastId : entry.keySet()) { + // Found broadcastId which is paused by host but not synced + if (!getAllSources(device).stream() + .anyMatch(rs -> (rs.getBroadcastId() == broadcastId)) + && isHostPauseType(broadcastId)) { + stopBigMonitoring(broadcastId, /* hostInitiated= */ false); + removeSinkMetadata(device, broadcastId); + return; + } + } + } + } + + private Boolean isAddedToSelectSourceRequest(int broadcastId, boolean priorityImportant) { + synchronized (mSourceSyncRequestsQueue) { + if (getBroadcastIdForSyncHandle(BassConstants.PENDING_SYNC_HANDLE) == broadcastId) { + return true; + } + + for (SourceSyncRequest sourceSyncRequest : mSourceSyncRequestsQueue) { + if (BassUtils.getBroadcastId(sourceSyncRequest.getScanResult()) == broadcastId) { + return !priorityImportant || sourceSyncRequest.hasPriority(); + } + } + } + + return false; } /** @@ -3099,7 +3315,7 @@ public class BassClientService extends ProfileService { + (", sourceMetadata: " + sourceMetadata) + (", isGroupOp: " + isGroupOp)); - List<BluetoothDevice> devices = getTargetDeviceList(sink, isGroupOp); + List<BluetoothDevice> devices = getTargetDeviceList(sink, /* isGroupOp= */ isGroupOp); // Don't coordinate it as a group if there's no group or there is one device only if (devices.size() < 2) { isGroupOp = false; @@ -3149,48 +3365,50 @@ public class BassClientService extends ProfileService { } } - if (leaudioBroadcastExtractPeriodicScannerFromStateMachine()) { - List<Integer> activeSyncedSrc = getActiveSyncedSources(); - BluetoothDevice sourceDevice = sourceMetadata.getSourceDevice(); - if (!isLocalBroadcast(sourceMetadata) - && (!activeSyncedSrc.contains( - getSyncHandleForBroadcastId(sourceMetadata.getBroadcastId())))) { - log("Adding inactive source: " + sourceDevice); - int broadcastId = sourceMetadata.getBroadcastId(); - if (broadcastId != BassConstants.INVALID_BROADCAST_ID - && getCachedBroadcast(broadcastId) != null) { - // If the source has been synced before, try to re-sync - // with the source by previously cached scan result. - // Check if not added already - boolean alreadyAdded = false; - synchronized (mPendingSourcesToAdd) { - for (AddSourceData pendingSourcesToAdd : mPendingSourcesToAdd) { - if (pendingSourcesToAdd.mSourceMetadata.getBroadcastId() - == broadcastId) { - alreadyAdded = true; - } - } - mPendingSourcesToAdd.add( - new AddSourceData(sink, sourceMetadata, isGroupOp)); - if (!alreadyAdded) { - addSelectSourceRequest(broadcastId, true); - } - } - } else { - log("AddSource: broadcast not cached or invalid, broadcastId: " + broadcastId); - mCallbacks.notifySourceAddFailed( - sink, sourceMetadata, BluetoothStatusCodes.ERROR_BAD_PARAMETERS); - } - return; - } - } - // Remove pausedBroadcastId in case that broadcast was paused before. mPausedBroadcastIds.remove(sourceMetadata.getBroadcastId()); logPausedBroadcastsAndSinks(); - byte[] code = sourceMetadata.getBroadcastCode(); for (BluetoothDevice device : devices) { + if (leaudioBroadcastExtractPeriodicScannerFromStateMachine()) { + List<Integer> activeSyncedSrc = getActiveSyncedSources(); + BluetoothDevice sourceDevice = sourceMetadata.getSourceDevice(); + if (!isLocalBroadcast(sourceMetadata) + && (!activeSyncedSrc.contains( + getSyncHandleForBroadcastId(sourceMetadata.getBroadcastId())))) { + log("Adding inactive source: " + sourceDevice); + int broadcastId = sourceMetadata.getBroadcastId(); + if (broadcastId != BassConstants.INVALID_BROADCAST_ID) { + // Check if not added already + if (isAddedToSelectSourceRequest(broadcastId, true)) { + mPendingSourcesToAdd.add( + new AddSourceData(device, sourceMetadata, isGroupOp)); + // If the source has been synced before, try to re-sync + // with the source by previously cached scan result. + } else if (getCachedBroadcast(broadcastId) != null) { + mPendingSourcesToAdd.add( + new AddSourceData(device, sourceMetadata, isGroupOp)); + addSelectSourceRequest(broadcastId, /* hasPriority= */ true); + } else { + Log.w( + TAG, + "AddSource: broadcast not cached, broadcastId: " + broadcastId); + mCallbacks.notifySourceAddFailed( + sink, + sourceMetadata, + BluetoothStatusCodes.ERROR_BAD_PARAMETERS); + return; + } + } else { + Log.w(TAG, "AddSource: invalid broadcastId"); + mCallbacks.notifySourceAddFailed( + sink, sourceMetadata, BluetoothStatusCodes.ERROR_BAD_PARAMETERS); + return; + } + continue; + } + } + BassClientStateMachine stateMachine = getOrCreateStateMachine(device); int statusCode = validateParametersForSourceOperation(stateMachine, device, sourceMetadata); @@ -3230,10 +3448,12 @@ public class BassClientService extends ProfileService { BluetoothLeBroadcastMetadata metaData = stateMachine.getCurrentBroadcastMetadata(sourceIdToRemove); if (metaData != null) { + removeSinkMetadata(device, metaData.getBroadcastId()); + // Add host intentional pause if previous broadcast is different than // current if (sourceMetadata.getBroadcastId() != metaData.getBroadcastId()) { - stopBigMonitoring(metaData.getBroadcastId(), true); + stopBigMonitoring(metaData.getBroadcastId(), /* hostInitiated= */ true); } } @@ -3286,6 +3506,11 @@ public class BassClientService extends ProfileService { } } + // Even if there is a room for broadcast, it could happen that all broadcasts were + // suspended via removing source. In that case, we have to found such broadcast and + // remove it from metadata. + checkIfBroadcastIsSuspendedBySourceRemovalAndClearData(device, stateMachine); + /* Store metadata for sink device */ storeSinkMetadata(device, sourceMetadata.getBroadcastId(), sourceMetadata); @@ -3309,6 +3534,8 @@ public class BassClientService extends ProfileService { Message message = stateMachine.obtainMessage(BassClientStateMachine.ADD_BCAST_SOURCE); message.obj = sourceMetadata; stateMachine.sendMessage(message); + + byte[] code = sourceMetadata.getBroadcastCode(); if (code != null && code.length != 0) { sEventLogger.logd( TAG, @@ -3341,28 +3568,24 @@ public class BassClientService extends ProfileService { + (", updatedMetadata: " + updatedMetadata)); Map<BluetoothDevice, Integer> devices = getGroupManagedDeviceSources(sink, sourceId).second; - if (updatedMetadata == null) { - log("modifySource: Error bad parameters: updatedMetadata cannot be null"); - for (BluetoothDevice device : devices.keySet()) { - mCallbacks.notifySourceModifyFailed( - device, sourceId, BluetoothStatusCodes.ERROR_BAD_PARAMETERS); - } - return; - } - - /* Update metadata for sink device */ - storeSinkMetadata(sink, updatedMetadata.getBroadcastId(), updatedMetadata); - byte[] code = updatedMetadata.getBroadcastCode(); for (Map.Entry<BluetoothDevice, Integer> deviceSourceIdPair : devices.entrySet()) { BluetoothDevice device = deviceSourceIdPair.getKey(); Integer deviceSourceId = deviceSourceIdPair.getValue(); + + if (updatedMetadata == null) { + log("modifySource: Error bad parameters: updatedMetadata cannot be null"); + mCallbacks.notifySourceModifyFailed( + device, deviceSourceId, BluetoothStatusCodes.ERROR_BAD_PARAMETERS); + continue; + } + BassClientStateMachine stateMachine = getOrCreateStateMachine(device); int statusCode = validateParametersForSourceOperation( stateMachine, device, updatedMetadata, deviceSourceId); if (statusCode != BluetoothStatusCodes.SUCCESS) { - mCallbacks.notifySourceModifyFailed(device, sourceId, statusCode); + mCallbacks.notifySourceModifyFailed(device, deviceSourceId, statusCode); continue; } if (stateMachine.hasPendingSourceOperation()) { @@ -3373,15 +3596,18 @@ public class BassClientService extends ProfileService { + ", broadcastId: " + updatedMetadata.getBroadcastId()); mCallbacks.notifySourceModifyFailed( - device, sourceId, BluetoothStatusCodes.ERROR_ALREADY_IN_TARGET_STATE); + device, deviceSourceId, BluetoothStatusCodes.ERROR_ALREADY_IN_TARGET_STATE); continue; } + /* Update metadata for sink device */ + storeSinkMetadata(device, updatedMetadata.getBroadcastId(), updatedMetadata); + sEventLogger.logd( TAG, "Modify Broadcast Source: " + ("device: " + device) - + ("sourceId: " + sourceId) + + ("sourceId: " + deviceSourceId) + (", updatedBroadcastId: " + updatedMetadata.getBroadcastId()) + (", updatedBroadcastName: " + updatedMetadata.getBroadcastName())); @@ -3391,12 +3617,14 @@ public class BassClientService extends ProfileService { message.arg2 = BassConstants.INVALID_PA_SYNC_VALUE; message.obj = updatedMetadata; stateMachine.sendMessage(message); + + byte[] code = updatedMetadata.getBroadcastCode(); if (code != null && code.length != 0) { sEventLogger.logd( TAG, "Set Broadcast Code (Modify Source context): " + ("device: " + device) - + ("sourceId: " + sourceId) + + ("sourceId: " + deviceSourceId) + (", updatedBroadcastId: " + updatedMetadata.getBroadcastId()) + (", updatedBroadcastName: " + updatedMetadata.getBroadcastName())); @@ -3409,7 +3637,10 @@ public class BassClientService extends ProfileService { } /** - * Removes the Broadcast Source from a Broadcast Sink + * A public method for removing a Broadcast Source from a Broadcast Sink. It also supports group + * removal if addSource was previously used with a group. Designed for external use, this method + * always removes sources along with their cached values, even if they were suspended, as this + * is intended by the user. * * @param sink representing the Broadcast Sink from which a Broadcast Source should be removed * @param sourceId source ID as delivered in onSourceAdded @@ -3420,8 +3651,10 @@ public class BassClientService extends ProfileService { Map<BluetoothDevice, Integer> devices = getGroupManagedDeviceSources(sink, sourceId).second; for (Map.Entry<BluetoothDevice, Integer> deviceSourceIdPair : devices.entrySet()) { BluetoothDevice device = deviceSourceIdPair.getKey(); - Integer deviceSourceId = deviceSourceIdPair.getValue(); + + mPausedBroadcastSinks.remove(device); + BassClientStateMachine stateMachine = getOrCreateStateMachine(device); int statusCode = validateParametersForSourceOperation(stateMachine, device, deviceSourceId); @@ -3433,63 +3666,87 @@ public class BassClientService extends ProfileService { BluetoothLeBroadcastMetadata metaData = stateMachine.getCurrentBroadcastMetadata(deviceSourceId); - - /* Removes metadata for sink device if not paused */ - if (!mPausedBroadcastSinks.contains(device)) { - if (metaData != null) { - removeSinkMetadata(device, metaData.getBroadcastId()); - } else { - removeSinkMetadata(device); - } - } - if (metaData != null) { - stopBigMonitoring(metaData.getBroadcastId(), true); + removeSinkMetadata(device, metaData.getBroadcastId()); + } else { + removeSinkMetadata(device); } - if (stateMachine.isSyncedToTheSource(deviceSourceId)) { - sEventLogger.logd( - TAG, - "Remove Broadcast Source(Force lost PA sync): " - + ("device: " + device) - + (", sourceId: " + deviceSourceId) - + (", broadcastId: " - + ((metaData == null) - ? BassConstants.INVALID_BROADCAST_ID - : metaData.getBroadcastId())) - + (", broadcastName: " - + ((metaData == null) ? "" : metaData.getBroadcastName()))); - - log("Force source to lost PA sync"); - Message message = - stateMachine.obtainMessage(BassClientStateMachine.UPDATE_BCAST_SOURCE); - message.arg1 = deviceSourceId; - message.arg2 = BassConstants.PA_SYNC_DO_NOT_SYNC; - /* Pending remove set. Remove source once not synchronized to PA */ - /* MetaData can be null if source is from remote's receive state */ - message.obj = metaData; - stateMachine.sendMessage(message); - continue; - } + removeSourceInternal(device, deviceSourceId, stateMachine, metaData); + } + } + + /** + * Removes the Broadcast Source from a single Broadcast Sink + * + * @param sink representing the Broadcast Sink from which a Broadcast Source should be removed + * @param sourceId source ID as delivered in onSourceAdded + */ + private void removeSourceInternal(BluetoothDevice sink, int sourceId) { + log("removeSourceInternal prepare: device: " + sink + ", sourceId: " + sourceId); + + BassClientStateMachine stateMachine = getOrCreateStateMachine(sink); + int statusCode = validateParametersForSourceOperation(stateMachine, sink, sourceId); + if (statusCode != BluetoothStatusCodes.SUCCESS) { + mCallbacks.notifySourceRemoveFailed(sink, sourceId, statusCode); + return; + } + BluetoothLeBroadcastMetadata metaData = stateMachine.getCurrentBroadcastMetadata(sourceId); + removeSourceInternal(sink, sourceId, stateMachine, metaData); + } + + /** + * Removes the Broadcast Source from a single Broadcast Sink + * + * @param sink representing the Broadcast Sink from which a Broadcast Source should be removed + * @param sourceId source ID as delivered in onSourceAdded + * @param stateMachine stateMachine for this sink + * @param metaData current broadcast metadata for this sink + */ + private void removeSourceInternal( + BluetoothDevice sink, + int sourceId, + BassClientStateMachine stateMachine, + BluetoothLeBroadcastMetadata metaData) { + log("removeSourceInternal: device: " + sink + ", sourceId: " + sourceId); + if (metaData != null) { + stopBigMonitoring(metaData.getBroadcastId(), /* hostInitiated= */ true); + } + if (stateMachine.isSyncedToTheSource(sourceId)) { sEventLogger.logd( TAG, - "Remove Broadcast Source: device: " + device + ", sourceId: " + deviceSourceId); + "Remove Broadcast Source(Force lost PA sync): " + + ("device: " + sink) + + (", sourceId: " + sourceId) + + (", broadcastId: " + + ((metaData == null) + ? BassConstants.INVALID_BROADCAST_ID + : metaData.getBroadcastId())) + + (", broadcastName: " + + ((metaData == null) ? "" : metaData.getBroadcastName()))); + + log("Force source to lost PA sync"); + Message message = + stateMachine.obtainMessage(BassClientStateMachine.UPDATE_BCAST_SOURCE); + message.arg1 = sourceId; + message.arg2 = BassConstants.PA_SYNC_DO_NOT_SYNC; + /* Pending remove set. Remove source once not synchronized to PA */ + /* MetaData can be null if source is from remote's receive state */ + message.obj = metaData; + stateMachine.sendMessage(message); + } else { + sEventLogger.logd( + TAG, "Remove Broadcast Source: device: " + sink + ", sourceId: " + sourceId); Message message = stateMachine.obtainMessage(BassClientStateMachine.REMOVE_BCAST_SOURCE); - message.arg1 = deviceSourceId; + message.arg1 = sourceId; stateMachine.sendMessage(message); } - for (Map.Entry<BluetoothDevice, Integer> deviceSourceIdPair : devices.entrySet()) { - BluetoothDevice device = deviceSourceIdPair.getKey(); - Integer deviceSourceId = deviceSourceIdPair.getValue(); - enqueueSourceGroupOp( - device, - BassClientStateMachine.REMOVE_BCAST_SOURCE, - Integer.valueOf(deviceSourceId)); - } + enqueueSourceGroupOp( + sink, BassClientStateMachine.REMOVE_BCAST_SOURCE, Integer.valueOf(sourceId)); } /** @@ -3630,10 +3887,6 @@ public class BassClientService extends ProfileService { getReceiveStateDevicePairs(broadcastId); for (Pair<BluetoothLeBroadcastReceiveState, BluetoothDevice> pair : sourcesToRemove) { - if (leaudioBroadcastResyncHelper()) { - mPausedBroadcastSinks.remove(pair.second); - stopBigMonitoring(pair.first.getBroadcastId(), true); - } removeSource(pair.second, pair.first.getSourceId()); } @@ -3643,11 +3896,17 @@ public class BassClientService extends ProfileService { } } - private void stopSourceReceivers(int broadcastId, boolean store) { + /** + * Stops or suspends source receivers for the given broadcast ID + * + * @param broadcastId The broadcast ID for which the receivers should be stopped or suspended + * @param store Determines whether the operation is a suspension (true) or a stop (false) + */ + private void stopOrSuspendSourceReceivers(int broadcastId, boolean store) { log("stopSourceReceivers broadcastId: " + broadcastId + ", store: " + store); Map<BluetoothDevice, Integer> sourcesToRemove = new HashMap<>(); - + HashSet<Integer> broadcastIdsToStopMonitoring = new HashSet<>(); for (BluetoothDevice device : getConnectedDevices()) { if (!leaudioBroadcastResyncHelper()) { if (mPausedBroadcastSinks.contains(device)) { @@ -3681,14 +3940,14 @@ public class BassClientService extends ProfileService { continue; } + broadcastIdsToStopMonitoring.add(receiveState.getBroadcastId()); + if (!mPausedBroadcastSinks.contains(device) || isSinkUnintentionalPauseType(receiveState.getBroadcastId())) { // Remove device if not paused yet sourcesToRemove.put(device, receiveState.getSourceId()); } - stopBigMonitoring(receiveState.getBroadcastId(), true); - if (store) { sEventLogger.logd(TAG, "Add broadcast sink to paused cache: " + device); mPausedBroadcastSinks.add(device); @@ -3699,10 +3958,12 @@ public class BassClientService extends ProfileService { } } - logPausedBroadcastsAndSinks(); + for (int broadcastIdToStopMonitoring : broadcastIdsToStopMonitoring) { + stopBigMonitoring(broadcastIdToStopMonitoring, /* hostInitiated= */ true); + } for (Map.Entry<BluetoothDevice, Integer> entry : sourcesToRemove.entrySet()) { - removeSource(entry.getKey(), entry.getValue()); + removeSourceInternal(entry.getKey(), entry.getValue()); } if (leaudioBroadcastResyncHelper()) { @@ -3853,7 +4114,8 @@ public class BassClientService extends ProfileService { Log.d(TAG, "handleBassStateReady: no metadata available"); continue; } - for (BluetoothDevice groupDevice : getTargetDeviceList(sink, true)) { + for (BluetoothDevice groupDevice : + getTargetDeviceList(sink, /* isGroupOp= */ true)) { if (groupDevice.equals(sink)) { continue; } @@ -3869,7 +4131,7 @@ public class BassClientService extends ProfileService { (rs.getBroadcastId() == receiver.get().getBroadcastId()))) { Log.d(TAG, "handleBassStateReady: restore the source for device, " + sink); - addSource(sink, metadata, false); + addSource(sink, metadata, /* isGroupOp= */ false); return; } } @@ -3967,7 +4229,12 @@ public class BassClientService extends ProfileService { if (!isAnyReceiverSyncedToBroadcast(pausedBroadcastId)) { mTimeoutHandler.stop(pausedBroadcastId, MESSAGE_BIG_MONITOR_TIMEOUT); mTimeoutHandler.stop(pausedBroadcastId, MESSAGE_BROADCAST_MONITOR_TIMEOUT); - iterator.remove(); + + if (isSinkUnintentionalPauseType(pausedBroadcastId) + || (isHostPauseType(pausedBroadcastId) + && mPausedBroadcastSinks.isEmpty())) { + iterator.remove(); + } synchronized (mSearchScanCallbackLock) { // when searching is stopped then stop active sync if (!isSearchInProgress()) { @@ -3992,13 +4259,29 @@ public class BassClientService extends ProfileService { mPausedBroadcastIds.remove(broadcastId); mPausedBroadcastSinks.clear(); } + stopActiveSync(broadcastId); + logPausedBroadcastsAndSinks(); + } + + private void stopActiveSync(int broadcastId) { synchronized (mSearchScanCallbackLock) { // when searching is stopped then stop active sync if (!isSearchInProgress()) { - cancelActiveSync(getSyncHandleForBroadcastId(broadcastId)); + if (leaudioMonitorUnicastSourceWhenManagedByBroadcastDelegator()) { + boolean waitingForPast = false; + synchronized (mSinksWaitingForPast) { + waitingForPast = + mSinksWaitingForPast.entrySet().stream() + .anyMatch(entry -> entry.getValue().first == broadcastId); + } + if (!waitingForPast) { + cancelActiveSync(getSyncHandleForBroadcastId(broadcastId)); + } + } else { + cancelActiveSync(getSyncHandleForBroadcastId(broadcastId)); + } } } - logPausedBroadcastsAndSinks(); } /** Cache suspending sources when broadcast paused */ @@ -4017,13 +4300,13 @@ public class BassClientService extends ProfileService { /** Request receivers to suspend broadcast sources synchronization */ public void suspendReceiversSourceSynchronization(int broadcastId) { sEventLogger.logd(TAG, "Suspend receivers source synchronization: " + broadcastId); - stopSourceReceivers(broadcastId, true); + stopOrSuspendSourceReceivers(broadcastId, /* store= */ true); } /** Request all receivers to suspend broadcast sources synchronization */ public void suspendAllReceiversSourceSynchronization() { sEventLogger.logd(TAG, "Suspend all receivers source synchronization"); - stopSourceReceivers(BassConstants.INVALID_BROADCAST_ID, true); + stopOrSuspendSourceReceivers(BassConstants.INVALID_BROADCAST_ID, /* store= */ true); } /** Request receivers to stop broadcast sources synchronization and remove them */ @@ -4032,7 +4315,7 @@ public class BassClientService extends ProfileService { if (leaudioBroadcastAssistantPeripheralEntrustment()) { stopSourceReceivers(broadcastId); } else { - stopSourceReceivers(broadcastId, false); + stopOrSuspendSourceReceivers(broadcastId, /* store= */ false); } } @@ -4092,12 +4375,12 @@ public class BassClientService extends ProfileService { int sourceId = receiveState.get().getSourceId(); updateSourceToResumeBroadcast(sink, sourceId, metadata); } else { - addSource(sink, metadata, false); + addSource(sink, metadata, /* isGroupOp= */ false); } } else { if (metadata != null) { mPausedBroadcastIds.remove(metadata.getBroadcastId()); - addSource(sink, metadata, false); + addSource(sink, metadata, /* isGroupOp= */ false); } else { Log.w( TAG, @@ -4167,7 +4450,7 @@ public class BassClientService extends ProfileService { getReceiveStateDevicePairs(BassConstants.INVALID_BROADCAST_ID); for (Pair<BluetoothLeBroadcastReceiveState, BluetoothDevice> pair : sourcesToStop) { - stopBigMonitoring(pair.first.getBroadcastId(), true); + stopBigMonitoring(pair.first.getBroadcastId(), /* hostInitiated= */ true); } } else { suspendAllReceiversSourceSynchronization(); @@ -4358,6 +4641,56 @@ public class BassClientService extends ProfileService { && syncState != BassConstants.BCAST_RCVR_STATE_BIS_SYNC_FAILED_SYNC_TO_BIG; } + private Set<Integer> getBroadcastIdsOfSyncedBroadcasters() { + HashSet<Integer> broadcastIds = new HashSet<>(); + List<Integer> activeSyncedSrc = new ArrayList<>(getActiveSyncedSources()); + for (int syncHandle : activeSyncedSrc) { + broadcastIds.add(getBroadcastIdForSyncHandle(syncHandle)); + } + return broadcastIds; + } + + private Set<Integer> getBroadcastIdsWaitingForPAST() { + HashSet<Integer> broadcastIds = new HashSet<>(); + synchronized (mSinksWaitingForPast) { + for (Map.Entry<BluetoothDevice, Pair<Integer, Integer>> entry : + mSinksWaitingForPast.entrySet()) { + broadcastIds.add(entry.getValue().first); + } + } + return broadcastIds; + } + + private Set<Integer> getBroadcastIdsWaitingForAddSource() { + HashSet<Integer> broadcastIds = new HashSet<>(); + synchronized (mPendingSourcesToAdd) { + for (AddSourceData pendingSourcesToAdd : mPendingSourcesToAdd) { + broadcastIds.add(pendingSourcesToAdd.mSourceMetadata.getBroadcastId()); + } + } + return broadcastIds; + } + + private Set<Integer> getPausedBroadcastIdsBasedOnSinks() { + HashSet<Integer> broadcastIds = new HashSet<>(); + for (BluetoothDevice pausedSink : mPausedBroadcastSinks) { + Map<Integer, BluetoothLeBroadcastMetadata> entry = + mBroadcastMetadataMap.getOrDefault(pausedSink, Collections.emptyMap()); + broadcastIds.addAll(entry.keySet()); + } + return broadcastIds; + } + + private Set<Integer> getUnintentionallyPausedBroadcastIds() { + HashSet<Integer> broadcastIds = new HashSet<>(); + for (int pausedBroadcastId : mPausedBroadcastIds.keySet()) { + if (isSinkUnintentionalPauseType(pausedBroadcastId)) { + broadcastIds.add(pausedBroadcastId); + } + } + return broadcastIds; + } + /** Handle broadcast state changed */ public void notifyBroadcastStateChanged(int state, int broadcastId) { switch (state) { @@ -4628,6 +4961,7 @@ public class BassClientService extends ProfileService { void notifySourceAddFailed( BluetoothDevice sink, BluetoothLeBroadcastMetadata source, int reason) { sService.checkAndResetGroupAllowedContextMask(); + sService.localNotifySourceAddFailed(sink, source); sEventLogger.loge( TAG, diff --git a/android/app/src/com/android/bluetooth/bass_client/BassClientStateMachine.java b/android/app/src/com/android/bluetooth/bass_client/BassClientStateMachine.java index 4a3e27b3eb..fb855f1946 100644 --- a/android/app/src/com/android/bluetooth/bass_client/BassClientStateMachine.java +++ b/android/app/src/com/android/bluetooth/bass_client/BassClientStateMachine.java @@ -847,7 +847,8 @@ class BassClientStateMachine extends StateMachine { recvState.getSourceDevice(), broadcastId); if (result != null) { int syncHandle = result.getSyncHandle(); - if (syncHandle != BassConstants.INVALID_SYNC_HANDLE) { + if (syncHandle != BassConstants.INVALID_SYNC_HANDLE + && syncHandle != BassConstants.PENDING_SYNC_HANDLE) { initiatePaSyncTransfer(syncHandle, sourceId); return; } diff --git a/android/app/src/com/android/bluetooth/bass_client/BassConstants.java b/android/app/src/com/android/bluetooth/bass_client/BassConstants.java index 5efd2d4185..768f32b7d9 100644 --- a/android/app/src/com/android/bluetooth/bass_client/BassConstants.java +++ b/android/app/src/com/android/bluetooth/bass_client/BassConstants.java @@ -37,6 +37,7 @@ public class BassConstants { ParcelUuid.fromString("00001856-0000-1000-8000-00805F9B34FB"); public static final int INVALID_SYNC_HANDLE = -1; + public static final int PENDING_SYNC_HANDLE = -2; public static final int INVALID_ADV_SID = -1; public static final int INVALID_ADV_ADDRESS_TYPE = -1; public static final int INVALID_ADV_INTERVAL = -1; diff --git a/android/app/src/com/android/bluetooth/bass_client/BassUtils.java b/android/app/src/com/android/bluetooth/bass_client/BassUtils.java index 5c15cf6880..02c38be501 100644 --- a/android/app/src/com/android/bluetooth/bass_client/BassUtils.java +++ b/android/app/src/com/android/bluetooth/bass_client/BassUtils.java @@ -18,12 +18,18 @@ package com.android.bluetooth.bass_client; import static com.android.bluetooth.flags.Flags.leaudioBassScanWithInternalScanController; +import android.bluetooth.BluetoothUtils; +import android.bluetooth.BluetoothUtils.TypeValueEntry; import android.bluetooth.le.ScanFilter; +import android.bluetooth.le.ScanRecord; +import android.bluetooth.le.ScanResult; import android.os.ParcelUuid; import android.util.Log; +import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.List; +import java.util.Map; /** Bass Utility functions */ class BassUtils { @@ -52,6 +58,88 @@ class BassUtils { return broadcastId; } + static Integer getBroadcastId(ScanResult scanResult) { + if (scanResult == null) { + Log.e(TAG, "Null scan result"); + return BassConstants.INVALID_BROADCAST_ID; + } + + return getBroadcastId(scanResult.getScanRecord()); + } + + static Integer getBroadcastId(ScanRecord scanRecord) { + if (scanRecord == null) { + Log.e(TAG, "Null scan record"); + return BassConstants.INVALID_BROADCAST_ID; + } + + Map<ParcelUuid, byte[]> listOfUuids = scanRecord.getServiceData(); + if (listOfUuids == null) { + Log.e(TAG, "Null service data"); + return BassConstants.INVALID_BROADCAST_ID; + } + + if (listOfUuids.containsKey(BassConstants.BAAS_UUID)) { + byte[] bId = listOfUuids.get(BassConstants.BAAS_UUID); + return BassUtils.parseBroadcastId(bId); + } else { + Log.e(TAG, "No broadcast Id in service data"); + } + + return BassConstants.INVALID_BROADCAST_ID; + } + + static PublicBroadcastData getPublicBroadcastData(ScanRecord scanRecord) { + if (scanRecord == null) { + Log.e(TAG, "Null scan record"); + return null; + } + + Map<ParcelUuid, byte[]> listOfUuids = scanRecord.getServiceData(); + if (listOfUuids == null) { + Log.e(TAG, "Null service data"); + return null; + } + + if (listOfUuids.containsKey(BassConstants.PUBLIC_BROADCAST_UUID)) { + byte[] pbAnnouncement = listOfUuids.get(BassConstants.PUBLIC_BROADCAST_UUID); + return PublicBroadcastData.parsePublicBroadcastData(pbAnnouncement); + } else { + log("No public broadcast data in service data"); + } + + return null; + } + + static String getBroadcastName(ScanRecord scanRecord) { + if (scanRecord == null) { + Log.e(TAG, "Null scan record"); + return null; + } + byte[] rawBytes = scanRecord.getBytes(); + List<TypeValueEntry> entries = BluetoothUtils.parseLengthTypeValueBytes(rawBytes); + if (rawBytes.length > 0 && rawBytes[0] > 0 && entries.isEmpty()) { + Log.e(TAG, "Invalid LTV entries in Scan record"); + return null; + } + + String broadcastName = null; + for (TypeValueEntry entry : entries) { + // Only use the first value of each type + if (broadcastName == null && entry.getType() == BassConstants.BCAST_NAME_AD_TYPE) { + byte[] bytes = entry.getValue(); + int len = bytes.length; + if (len < BassConstants.BCAST_NAME_LEN_MIN + || len > BassConstants.BCAST_NAME_LEN_MAX) { + Log.e(TAG, "Invalid broadcast name length in Scan record" + len); + return null; + } + broadcastName = new String(bytes, StandardCharsets.UTF_8); + } + } + return broadcastName; + } + static void log(String msg) { Log.d(TAG, msg); } diff --git a/android/app/src/com/android/bluetooth/btservice/AdapterService.java b/android/app/src/com/android/bluetooth/btservice/AdapterService.java index 06fd3ad28f..90193813a5 100644 --- a/android/app/src/com/android/bluetooth/btservice/AdapterService.java +++ b/android/app/src/com/android/bluetooth/btservice/AdapterService.java @@ -1085,7 +1085,6 @@ public class AdapterService extends Service { mStartedProfiles.put(BluetoothProfile.GATT, mGattService); addProfile(mGattService); - mGattService.start(); mGattService.setAvailable(true); onProfileServiceStateChanged(mGattService, BluetoothAdapter.STATE_ON); } @@ -1571,7 +1570,6 @@ public class AdapterService extends Service { ProfileService profileService = PROFILE_CONSTRUCTORS.get(profileId).apply(this); mStartedProfiles.put(profileId, profileService); addProfile(profileService); - profileService.start(); profileService.setAvailable(true); // With `Flags.scanManagerRefactor()` GattService initialization is pushed back to // `ON` state instead of `BLE_ON`. Here we ensure mGattService is set prior diff --git a/android/app/src/com/android/bluetooth/btservice/BondStateMachine.java b/android/app/src/com/android/bluetooth/btservice/BondStateMachine.java index 6d5bb49338..62b5d3ee93 100644 --- a/android/app/src/com/android/bluetooth/btservice/BondStateMachine.java +++ b/android/app/src/com/android/bluetooth/btservice/BondStateMachine.java @@ -18,6 +18,9 @@ package com.android.bluetooth.btservice; import static android.Manifest.permission.BLUETOOTH_CONNECT; +import static com.android.bluetooth.BluetoothStatsLog.BLUETOOTH_CROSS_LAYER_EVENT_REPORTED__EVENT_TYPE__BOND_RETRY; +import static com.android.bluetooth.BluetoothStatsLog.BLUETOOTH_CROSS_LAYER_EVENT_REPORTED__STATE__FAIL; + import android.app.Activity; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothClass; @@ -172,6 +175,12 @@ final class BondStateMachine extends StateMachine { sendMessageDelayed(new_msg, BOND_RETRY_DELAY_MS); return true; } else { + MetricsLogger.getInstance() + .logBluetoothEvent( + dev, + BLUETOOTH_CROSS_LAYER_EVENT_REPORTED__EVENT_TYPE__BOND_RETRY, + BLUETOOTH_CROSS_LAYER_EVENT_REPORTED__STATE__FAIL, + 0); Log.w(TAG, "Native was busy - the bond will most likely fail!"); } } diff --git a/android/app/src/com/android/bluetooth/btservice/ProfileService.java b/android/app/src/com/android/bluetooth/btservice/ProfileService.java index 321f8f99cc..c0e9e8e2fd 100644 --- a/android/app/src/com/android/bluetooth/btservice/ProfileService.java +++ b/android/app/src/com/android/bluetooth/btservice/ProfileService.java @@ -61,9 +61,6 @@ public abstract class ProfileService extends ContextWrapper { */ protected abstract IProfileServiceBinder initBinder(); - /** Start service */ - public void start() {} - /** Stop service */ public abstract void stop(); diff --git a/android/app/src/com/android/bluetooth/btservice/RemoteDevices.java b/android/app/src/com/android/bluetooth/btservice/RemoteDevices.java index f297d905ac..c9995d22ce 100644 --- a/android/app/src/com/android/bluetooth/btservice/RemoteDevices.java +++ b/android/app/src/com/android/bluetooth/btservice/RemoteDevices.java @@ -535,7 +535,7 @@ public class RemoteDevices { } } - return result.toArray(new ParcelUuid[combinedUuidsLength]); + return result.toArray(new ParcelUuid[result.size()]); } } diff --git a/android/app/src/com/android/bluetooth/hfpclient/NativeInterface.java b/android/app/src/com/android/bluetooth/hfpclient/NativeInterface.java index 914416b0ec..a4ce2551f4 100644 --- a/android/app/src/com/android/bluetooth/hfpclient/NativeInterface.java +++ b/android/app/src/com/android/bluetooth/hfpclient/NativeInterface.java @@ -15,11 +15,13 @@ */ /* - * Defines the native inteface that is used by state machine/service to either or receive messages + * Defines the native interface that is used by state machine/service to either or receive messages * from the native stack. This file is registered for the native methods in corresponding CPP file. */ package com.android.bluetooth.hfpclient; +import static java.util.Objects.requireNonNull; + import android.bluetooth.BluetoothDevice; import android.util.Log; @@ -29,8 +31,6 @@ import com.android.bluetooth.flags.Flags; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; -import java.util.Objects; - /** * Defines native calls that are used by state machine/service to either send or receive messages * to/from the native stack. This file is registered for the native methods in corresponding CPP @@ -39,18 +39,16 @@ import java.util.Objects; public class NativeInterface { private static final String TAG = NativeInterface.class.getSimpleName(); - private AdapterService mAdapterService; + private final AdapterService mAdapterService; @GuardedBy("INSTANCE_LOCK") private static NativeInterface sInstance; private static final Object INSTANCE_LOCK = new Object(); - private NativeInterface() { - mAdapterService = - Objects.requireNonNull( - AdapterService.getAdapterService(), - "AdapterService cannot be null when NativeInterface init"); + @VisibleForTesting + NativeInterface(AdapterService adapterService) { + mAdapterService = requireNonNull(adapterService); } /** @@ -61,7 +59,7 @@ public class NativeInterface { public static NativeInterface getInstance() { synchronized (INSTANCE_LOCK) { if (sInstance == null) { - sInstance = new NativeInterface(); + sInstance = new NativeInterface(AdapterService.getAdapterService()); } return sInstance; } diff --git a/android/app/src/com/android/bluetooth/hfpclient/VendorCommandResponseProcessor.java b/android/app/src/com/android/bluetooth/hfpclient/VendorCommandResponseProcessor.java index 061df3b282..fbe6e2f299 100644 --- a/android/app/src/com/android/bluetooth/hfpclient/VendorCommandResponseProcessor.java +++ b/android/app/src/com/android/bluetooth/hfpclient/VendorCommandResponseProcessor.java @@ -15,7 +15,7 @@ */ /* - * Defines utility inteface that is used by state machine/service to either send vendor specific AT + * Defines utility interface that is used by state machine/service to either send vendor specific AT * command or receive vendor specific response from the native stack. */ package com.android.bluetooth.hfpclient; diff --git a/android/app/src/com/android/bluetooth/le_scan/ScanController.java b/android/app/src/com/android/bluetooth/le_scan/ScanController.java index c03bdb0002..f41f6c46e5 100644 --- a/android/app/src/com/android/bluetooth/le_scan/ScanController.java +++ b/android/app/src/com/android/bluetooth/le_scan/ScanController.java @@ -20,8 +20,8 @@ import static android.Manifest.permission.BLUETOOTH_PRIVILEGED; import static android.Manifest.permission.BLUETOOTH_SCAN; import static android.Manifest.permission.UPDATE_DEVICE_STATS; -import static com.android.bluetooth.flags.Flags.leaudioBassScanWithInternalScanController; import static com.android.bluetooth.Utils.checkCallerTargetSdk; +import static com.android.bluetooth.flags.Flags.leaudioBassScanWithInternalScanController; import static java.util.Objects.requireNonNull; @@ -402,7 +402,9 @@ public class ScanController { + ", originalAddress=" + originalAddress); - String identityAddress = mAdapterService.getIdentityAddress(address); + // Retain the original behavior of returning bluetoothAddress when identityAddress is null + String identityAddress = Utils.getBrEdrAddress(address, mAdapterService); + if (!address.equals(identityAddress)) { Log.v( TAG, diff --git a/android/app/src/com/android/bluetooth/le_scan/ScanManager.java b/android/app/src/com/android/bluetooth/le_scan/ScanManager.java index c9d3774eb2..9528e84c93 100644 --- a/android/app/src/com/android/bluetooth/le_scan/ScanManager.java +++ b/android/app/src/com/android/bluetooth/le_scan/ScanManager.java @@ -1098,9 +1098,13 @@ public class ScanManager { mLastConfiguredScanSettingCoded != Integer.MIN_VALUE); int scanPhyMask = getScanPhyMask(client1m != null, clientCoded != null); + // Only update scan parameters if at least one of the following is true: + // 1. The 1M PHY mode has changed and is a valid value + // 2. The coded PHY mode has changed and is a valid value + // 3. The PHYs to scan on have changed and the new setting is valid (not 0) if (shouldUpdateScan(newScanSetting1m, mLastConfiguredScanSetting1m) || shouldUpdateScan(newScanSettingCoded, mLastConfiguredScanSettingCoded) - || curPhyMask != scanPhyMask) { + || (scanPhyMask != 0 && curPhyMask != scanPhyMask)) { int scanWindow1m = getScanWindow(client1m); int scanInterval1m = getScanInterval(client1m); int scanWindowCoded = getScanWindow(clientCoded); diff --git a/android/app/src/com/android/bluetooth/mcp/MediaControlGattService.java b/android/app/src/com/android/bluetooth/mcp/MediaControlGattService.java index 49b0c49038..06123cbd71 100644 --- a/android/app/src/com/android/bluetooth/mcp/MediaControlGattService.java +++ b/android/app/src/com/android/bluetooth/mcp/MediaControlGattService.java @@ -238,14 +238,15 @@ public class MediaControlGattService implements MediaControlGattServiceInterface Operation operation, int requestId, BluetoothGattCharacteristic characteristic, - BluetoothGattDescriptor descriptor) { + BluetoothGattDescriptor descriptor, + int offset) { mOperation = operation; mRequestId = requestId; mCharacteristic = characteristic; mDescriptor = descriptor; mPreparedWrite = false; mResponseNeeded = false; - mOffset = 0; + mOffset = offset; mValue = null; } @@ -693,17 +694,24 @@ public class MediaControlGattService implements MediaControlGattServiceInterface Arrays.copyOfRange(bb.array(), op.mOffset, Integer.BYTES)); return; } + byte[] readRespValue = op.mCharacteristic.getValue(); + if (readRespValue != null) { + if (readRespValue.length >= op.mOffset) { + status = BluetoothGatt.GATT_SUCCESS; + readRespValue = + Arrays.copyOfRange(readRespValue, op.mOffset, readRespValue.length); + } else { + Log.e( + TAG, + ("Wrong offset read for: " + op.mCharacteristic.getUuid()) + + (": offset " + op.mOffset) + + (", total len: " + readRespValue.length)); + status = BluetoothGatt.GATT_INVALID_OFFSET; + readRespValue = new byte[] {}; + } - if (op.mCharacteristic.getValue() != null) { mBluetoothGattServer.sendResponse( - device, - op.mRequestId, - BluetoothGatt.GATT_SUCCESS, - op.mOffset, - Arrays.copyOfRange( - op.mCharacteristic.getValue(), - op.mOffset, - op.mCharacteristic.getValue().length)); + device, op.mRequestId, status, op.mOffset, readRespValue); } else { Log.e( TAG, @@ -981,7 +989,8 @@ public class MediaControlGattService implements MediaControlGattServiceInterface GattOpContext.Operation.READ_CHARACTERISTIC, requestId, characteristic, - null); + null, + offset); switch (getDeviceAuthorization(device)) { case BluetoothDevice.ACCESS_REJECTED: onRejectedAuthorizationGattOperation(device, op); @@ -1073,7 +1082,8 @@ public class MediaControlGattService implements MediaControlGattServiceInterface GattOpContext.Operation.READ_DESCRIPTOR, requestId, null, - descriptor); + descriptor, + offset); switch (getDeviceAuthorization(device)) { case BluetoothDevice.ACCESS_REJECTED: onRejectedAuthorizationGattOperation(device, op); diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppNotification.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppNotification.java index 8f9860ade6..61fcb794bd 100644 --- a/android/app/src/com/android/bluetooth/opp/BluetoothOppNotification.java +++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppNotification.java @@ -51,6 +51,7 @@ import android.util.Log; import com.android.bluetooth.BluetoothMethodProxy; import com.android.bluetooth.R; import com.android.bluetooth.Utils; +import com.android.bluetooth.flags.Flags; import com.google.common.annotations.VisibleForTesting; @@ -630,6 +631,11 @@ class BluetoothOppNotification { .setLocalOnly(true); mNotificationMgr.notify(NOTIFICATION_ID_COMPLETE_SUMMARY, b.build()); + } else if (Flags.oppRemoveEmptyGroupNotification() && inboundNum == 0 && outboundNum == 0) { + if (mNotificationMgr != null) { + mNotificationMgr.cancel(NOTIFICATION_ID_COMPLETE_SUMMARY); + Log.v(TAG, "empty group summary notification was removed."); + } } } diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppObexClientSession.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppObexClientSession.java index f862ddc301..e2880b14e9 100644 --- a/android/app/src/com/android/bluetooth/opp/BluetoothOppObexClientSession.java +++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppObexClientSession.java @@ -32,6 +32,8 @@ package com.android.bluetooth.opp; +import static java.util.Objects.requireNonNull; + import android.bluetooth.BluetoothProfile; import android.bluetooth.BluetoothProtoEnums; import android.content.ContentValues; @@ -50,6 +52,7 @@ import com.android.bluetooth.BluetoothMetricsProto; import com.android.bluetooth.BluetoothStatsLog; import com.android.bluetooth.btservice.MetricsLogger; import com.android.bluetooth.content_profiles.ContentProfileErrorReportUtils; +import com.android.internal.annotations.GuardedBy; import com.android.obex.ClientOperation; import com.android.obex.ClientSession; import com.android.obex.HeaderSet; @@ -69,30 +72,23 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession { private static final String TAG = "BtOppObexClient"; - private ClientThread mThread; - - private ObexTransport mTransport; - - private Context mContext; + private final ObexTransport mTransport; + private final Context mContext; + private ClientThread mThread; private volatile boolean mInterrupted; - @VisibleForTesting volatile boolean mWaitingForRemote; - private int mNumFilesAttemptedToSend; public BluetoothOppObexClientSession(Context context, ObexTransport transport) { - if (transport == null) { - throw new NullPointerException("transport is null"); - } - mContext = context; - mTransport = transport; + mContext = requireNonNull(context); + mTransport = requireNonNull(transport); } @Override public void start(Handler handler, int numShares) { Log.d(TAG, "Start!"); - mThread = new ClientThread(mContext, mTransport, numShares, handler); + mThread = new ClientThread(numShares, handler); mThread.start(); } @@ -128,38 +124,28 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession { @VisibleForTesting class ClientThread extends Thread { - private static final int SLEEP_TIME = 500; - private Context mContext1; - - private BluetoothOppShareInfo mInfo; - - private volatile boolean mWaitingForShare; + private final WakeLock mWakeLock = + mContext.getSystemService(PowerManager.class) + .newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG); + private final Handler mCallbackHandler; + private final int mNumShares; - private ObexTransport mTransport1; + @GuardedBy("this") + @VisibleForTesting + volatile boolean mWaitingForRemote = false; + private volatile boolean mWaitingForShare = true; @VisibleForTesting ClientSession mCs; - - private WakeLock mWakeLock; - private BluetoothOppSendFileInfo mFileInfo = null; - private boolean mConnected = false; + private BluetoothOppShareInfo mInfo; - private int mNumShares; - private final Handler mCallbackHandler; - - ClientThread( - Context context, ObexTransport transport, int initialNumShares, Handler callback) { + ClientThread(int initialNumShares, Handler callback) { super("BtOpp ClientThread"); - mContext1 = context; - mTransport1 = transport; mWaitingForShare = true; - mWaitingForRemote = false; mNumShares = initialNumShares; - PowerManager pm = mContext.getSystemService(PowerManager.class); - mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG); mCallbackHandler = callback; } @@ -255,25 +241,22 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession { 3); Log.w(TAG, "OBEX session close error" + e); } - if (mTransport1 != null) { - try { - mTransport1.close(); - } catch (IOException e) { - ContentProfileErrorReportUtils.report( - BluetoothProfile.OPP, - BluetoothProtoEnums.BLUETOOTH_OPP_OBEX_CLIENT_SESSION, - BluetoothStatsLog - .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, - 4); - Log.e(TAG, "mTransport.close error"); - } + try { + mTransport.close(); + } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_OBEX_CLIENT_SESSION, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 4); + Log.e(TAG, "mTransport.close error"); } } private void connect(int numShares) { - Log.d(TAG, "Create ClientSession with transport " + mTransport1.toString()); + Log.d(TAG, "Create ClientSession with transport " + mTransport.toString()); try { - mCs = new ClientSession(mTransport1); + mCs = new ClientSession(mTransport); mConnected = true; } catch (IOException e1) { ContentProfileErrorReportUtils.report( @@ -341,7 +324,7 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession { } mWaitingForShare = true; } else { - Constants.updateShareStatus(mContext1, mInfo.mId, status); + Constants.updateShareStatus(mContext, mInfo.mId, status); } Message msg = Message.obtain(mCallbackHandler); @@ -363,7 +346,7 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession { BluetoothOppSendFileInfo fileInfo = BluetoothOppUtility.getSendFileInfo(mInfo.mUri); if (fileInfo.mFileName == null || fileInfo.mLength == 0) { Log.v(TAG, "BluetoothOppSendFileInfo get invalid file"); - Constants.updateShareStatus(mContext1, mInfo.mId, fileInfo.mStatus); + Constants.updateShareStatus(mContext, mInfo.mId, fileInfo.mStatus); } else { Log.v(TAG, "Generate BluetoothOppSendFileInfo:"); @@ -379,7 +362,7 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession { updateValues.put(BluetoothShare.MIMETYPE, fileInfo.mMimetype); BluetoothMethodProxy.getInstance() .contentResolverUpdate( - mContext1.getContentResolver(), + mContext.getContentResolver(), contentUri, updateValues, null, @@ -410,8 +393,7 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession { request.setHeader(HeaderSet.TYPE, fileInfo.mMimetype); applyRemoteDeviceQuirks(request, mInfo.mDestination, fileInfo.mFileName); - Constants.updateShareStatus( - mContext1, mInfo.mId, BluetoothShare.STATUS_RUNNING); + Constants.updateShareStatus(mContext, mInfo.mId, BluetoothShare.STATUS_RUNNING); request.setHeader(HeaderSet.LENGTH, fileInfo.mLength); @@ -425,7 +407,7 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession { .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, 8); status = BluetoothShare.STATUS_OBEX_DATA_ERROR; - Constants.updateShareStatus(mContext1, mInfo.mId, status); + Constants.updateShareStatus(mContext, mInfo.mId, status); Log.e(TAG, "Error setting header items for request: " + e); error = true; @@ -437,7 +419,7 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession { .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, 9); status = BluetoothShare.STATUS_OBEX_DATA_ERROR; - Constants.updateShareStatus(mContext1, mInfo.mId, status); + Constants.updateShareStatus(mContext, mInfo.mId, status); Log.e(TAG, "Error when put HeaderSet "); error = true; @@ -459,7 +441,7 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession { .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, 10); status = BluetoothShare.STATUS_OBEX_DATA_ERROR; - Constants.updateShareStatus(mContext1, mInfo.mId, status); + Constants.updateShareStatus(mContext, mInfo.mId, status); Log.e(TAG, "Error when openOutputStream"); error = true; } @@ -468,7 +450,7 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession { updateValues = new ContentValues(); updateValues.put(BluetoothShare.CURRENT_BYTES, 0); updateValues.put(BluetoothShare.STATUS, BluetoothShare.STATUS_RUNNING); - mContext1.getContentResolver().update(contentUri, updateValues, null, null); + mContext.getContentResolver().update(contentUri, updateValues, null, null); } if (!error) { @@ -521,8 +503,7 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession { okToProceed = true; updateValues = new ContentValues(); updateValues.put(BluetoothShare.CURRENT_BYTES, position); - mContext1 - .getContentResolver() + mContext.getContentResolver() .update(contentUri, updateValues, null, null); mNumFilesAttemptedToSend++; } else { @@ -562,8 +543,7 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession { || currentTime - prevTimestamp > Constants.NFC_ALIVE_CHECK_MS) { updateValues = new ContentValues(); updateValues.put(BluetoothShare.CURRENT_BYTES, position); - mContext1 - .getContentResolver() + mContext.getContentResolver() .update(contentUri, updateValues, null, null); prevPercent = percent; prevTimestamp = currentTime; @@ -665,7 +645,7 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession { } } - Constants.updateShareStatus(mContext1, mInfo.mId, status); + Constants.updateShareStatus(mContext, mInfo.mId, status); if (inputStream != null) { inputStream.close(); @@ -686,7 +666,7 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession { // mark the transfer as failure. if (position != fileInfo.mLength) { status = BluetoothShare.STATUS_FORBIDDEN; - Constants.updateShareStatus(mContext1, mInfo.mId, status); + Constants.updateShareStatus(mContext, mInfo.mId, status); } } } @@ -698,8 +678,7 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession { Log.e(TAG, "Error when sending file: " + exception); // Update interrupted outbound content resolver entry when // error during transfer. - Constants.updateShareStatus( - mContext1, mInfo.mId, BluetoothShare.STATUS_OBEX_DATA_ERROR); + Constants.updateShareStatus(mContext, mInfo.mId, BluetoothShare.STATUS_OBEX_DATA_ERROR); mCallbackHandler.removeMessages(BluetoothOppObexSession.MSG_CONNECT_TIMEOUT); } @@ -710,7 +689,7 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession { if (mWaitingForRemote) { Log.v(TAG, "Interrupted when waitingForRemote"); try { - mTransport1.close(); + mTransport.close(); } catch (IOException e) { ContentProfileErrorReportUtils.report( BluetoothProfile.OPP, diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppObexServerSession.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppObexServerSession.java index f15567ddc1..2b703993f9 100644 --- a/android/app/src/com/android/bluetooth/opp/BluetoothOppObexServerSession.java +++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppObexServerSession.java @@ -73,47 +73,32 @@ import java.util.Arrays; // Next tag value for ContentProfileErrorReportUtils.report(): 15 public class BluetoothOppObexServerSession extends ServerRequestHandler implements BluetoothOppObexSession { - private static final String TAG = "BtOppObexServer"; - @VisibleForTesting public ObexTransport mTransport; - - @VisibleForTesting public Context mContext; + private final Context mContext; + private final ObexTransport mTransport; + private final WakeLock mPartialWakeLock; + private final BluetoothOppService mBluetoothOppService; + private long mTimestamp; + private boolean mInterrupted; + private int mLocalShareInfoId; // info id when we insert the record + private int mNumFilesAttemptedToReceive; + @VisibleForTesting boolean mTimeoutMsgSent; + @VisibleForTesting public ServerSession mSession; + @VisibleForTesting BluetoothOppReceiveFileInfo mFileInfo; + @VisibleForTesting public int mAccepted = BluetoothShare.USER_CONFIRMATION_PENDING; @VisibleForTesting public Handler mCallback = null; - + @VisibleForTesting public BluetoothOppShareInfo mInfo; // the current transfer info /* status when server is blocking for user/auto confirmation */ @VisibleForTesting public boolean mServerBlocking = true; - /* the current transfer info */ - @VisibleForTesting public BluetoothOppShareInfo mInfo; - - /* info id when we insert the record */ - private int mLocalShareInfoId; - - @VisibleForTesting public int mAccepted = BluetoothShare.USER_CONFIRMATION_PENDING; - - private boolean mInterrupted = false; - - @VisibleForTesting public ServerSession mSession; - - private long mTimestamp; - - @VisibleForTesting BluetoothOppReceiveFileInfo mFileInfo; - - private WakeLock mPartialWakeLock; - - @VisibleForTesting boolean mTimeoutMsgSent = false; - - @VisibleForTesting public BluetoothOppService mBluetoothOppService; - - private int mNumFilesAttemptedToReceive; - public BluetoothOppObexServerSession( Context context, ObexTransport transport, BluetoothOppService service) { mContext = context; mTransport = transport; mBluetoothOppService = service; + PowerManager pm = mContext.getSystemService(PowerManager.class); mPartialWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG); mPartialWakeLock.setReferenceCounted(false); diff --git a/android/app/tests/unit/src/com/android/bluetooth/TestLooper.java b/android/app/tests/unit/src/com/android/bluetooth/TestLooper.java index 31f4515578..ae64352e37 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/TestLooper.java +++ b/android/app/tests/unit/src/com/android/bluetooth/TestLooper.java @@ -27,6 +27,8 @@ import android.util.Log; import com.android.modules.utils.HandlerExecutor; +import com.google.common.util.concurrent.Uninterruptibles; + import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; @@ -298,11 +300,7 @@ public class TestLooper { if (mAutoDispatchThread.isAlive()) { mAutoDispatchThread.interrupt(); } - try { - mAutoDispatchThread.join(); - } catch (InterruptedException e) { - // Catch exception from join. - } + Uninterruptibles.joinUninterruptibly(mAutoDispatchThread); RuntimeException e = mAutoDispatchThread.getException(); mAutoDispatchThread = null; diff --git a/android/app/tests/unit/src/com/android/bluetooth/TestUtils.java b/android/app/tests/unit/src/com/android/bluetooth/TestUtils.java index 257f3d0806..106bc0008a 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/TestUtils.java +++ b/android/app/tests/unit/src/com/android/bluetooth/TestUtils.java @@ -19,7 +19,8 @@ import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.*; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; import android.annotation.IntRange; import android.bluetooth.BluetoothDevice; @@ -41,9 +42,12 @@ import androidx.test.uiautomator.UiDevice; import com.android.bluetooth.avrcpcontroller.BluetoothMediaBrowserService; import com.android.bluetooth.btservice.AdapterService; +import org.junit.rules.MethodRule; import org.junit.rules.TestRule; import org.junit.runner.Description; +import org.junit.runners.model.FrameworkMethod; import org.junit.runners.model.Statement; +import org.mockito.junit.MockitoJUnit; import java.time.Duration; import java.time.Instant; @@ -92,8 +96,8 @@ public class TestUtils { /** Helper function to mock getSystemService calls */ public static <T> void mockGetSystemService( Context ctx, String serviceName, Class<T> serviceClass, T mockService) { - when(ctx.getSystemService(eq(serviceName))).thenReturn(mockService); - when(ctx.getSystemServiceName(eq(serviceClass))).thenReturn(serviceName); + doReturn(mockService).when(ctx).getSystemService(eq(serviceName)); + doReturn(serviceName).when(ctx).getSystemServiceName(eq(serviceClass)); } /** Helper function to mock getSystemService calls */ @@ -323,6 +327,22 @@ public class TestUtils { } } + /** Wrapper around MockitoJUnit.rule() to be extended in follow-up. */ + public static class MockitoRule implements MethodRule { + private final org.mockito.junit.MockitoRule mMockitoRule = MockitoJUnit.rule(); + + public Statement apply(Statement base, FrameworkMethod method, Object target) { + Statement nestedStatement = mMockitoRule.apply(base, method, target); + + return new Statement() { + @Override + public void evaluate() throws Throwable { + nestedStatement.evaluate(); + } + }; + } + } + /** Helper class used to run synchronously a runnable action on a looper. */ private static final class SyncRunnable implements Runnable { private final Runnable mTarget; diff --git a/android/app/tests/unit/src/com/android/bluetooth/a2dp/A2dpCodecConfigTest.java b/android/app/tests/unit/src/com/android/bluetooth/a2dp/A2dpCodecConfigTest.java index 415be36b22..a6bf4950ca 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/a2dp/A2dpCodecConfigTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/a2dp/A2dpCodecConfigTest.java @@ -16,6 +16,7 @@ package com.android.bluetooth.a2dp; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.google.common.truth.Truth.assertThat; @@ -40,8 +41,6 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.util.Arrays; @@ -52,7 +51,7 @@ public class A2dpCodecConfigTest { private final BluetoothDevice mDevice = getTestDevice(56); private A2dpCodecConfig mA2dpCodecConfig; - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private Context mMockContext; @Mock private Resources mMockResources; diff --git a/android/app/tests/unit/src/com/android/bluetooth/a2dp/A2dpServiceBinderTest.java b/android/app/tests/unit/src/com/android/bluetooth/a2dp/A2dpServiceBinderTest.java index e8a0918b1c..0f41af59dd 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/a2dp/A2dpServiceBinderTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/a2dp/A2dpServiceBinderTest.java @@ -18,6 +18,7 @@ package com.android.bluetooth.a2dp; import static android.bluetooth.BluetoothCodecConfig.SOURCE_CODEC_TYPE_INVALID; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static org.mockito.Mockito.any; @@ -39,8 +40,6 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; public class A2dpServiceBinderTest { private static final AttributionSource sSource = new AttributionSource.Builder(0).build(); @@ -48,7 +47,7 @@ public class A2dpServiceBinderTest { @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private A2dpService mA2dpService; @Mock private PackageManager mPackageManager; diff --git a/android/app/tests/unit/src/com/android/bluetooth/a2dp/A2dpServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/a2dp/A2dpServiceTest.java index 87d721168b..ea42d29ab1 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/a2dp/A2dpServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/a2dp/A2dpServiceTest.java @@ -24,6 +24,7 @@ import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTING; import static androidx.test.espresso.intent.matcher.IntentMatchers.hasAction; import static androidx.test.espresso.intent.matcher.IntentMatchers.hasExtra; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.google.common.truth.Truth.assertThat; @@ -70,8 +71,6 @@ import org.mockito.ArgumentCaptor; import org.mockito.InOrder; import org.mockito.Mock; import org.mockito.hamcrest.MockitoHamcrest; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import platform.test.runner.parameterized.ParameterizedAndroidJunit4; import platform.test.runner.parameterized.Parameters; @@ -89,7 +88,7 @@ public class A2dpServiceTest { private final BluetoothDevice mDevice = getTestDevice(5); @Rule public final SetFlagsRule mSetFlagsRule; - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private A2dpNativeInterface mMockNativeInterface; @Mock private ActiveDeviceManager mActiveDeviceManager; @@ -200,7 +199,6 @@ public class A2dpServiceTest { // Verify that setActiveDevice(null) was called during shutdown verify(mMockNativeInterface).setActiveDevice(null); - mA2dpService.start(); } /** Test get priority for BluetoothDevice */ diff --git a/android/app/tests/unit/src/com/android/bluetooth/a2dp/A2dpStateMachineTest.java b/android/app/tests/unit/src/com/android/bluetooth/a2dp/A2dpStateMachineTest.java index 0bb41f61d9..bd79d386ed 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/a2dp/A2dpStateMachineTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/a2dp/A2dpStateMachineTest.java @@ -26,6 +26,7 @@ import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTED; import static androidx.test.espresso.intent.matcher.IntentMatchers.hasAction; import static androidx.test.espresso.intent.matcher.IntentMatchers.hasExtra; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.android.bluetooth.a2dp.A2dpStateMachine.MESSAGE_CONNECT; import static com.android.bluetooth.a2dp.A2dpStateMachine.MESSAGE_DISCONNECT; @@ -65,15 +66,13 @@ import org.junit.runner.RunWith; import org.mockito.InOrder; import org.mockito.Mock; import org.mockito.hamcrest.MockitoHamcrest; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.util.Arrays; @MediumTest @RunWith(AndroidJUnit4.class) public class A2dpStateMachineTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); diff --git a/android/app/tests/unit/src/com/android/bluetooth/a2dpsink/A2dpSinkServiceBinderTest.java b/android/app/tests/unit/src/com/android/bluetooth/a2dpsink/A2dpSinkServiceBinderTest.java index 055af52636..3c653bf444 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/a2dpsink/A2dpSinkServiceBinderTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/a2dpsink/A2dpSinkServiceBinderTest.java @@ -16,6 +16,7 @@ package com.android.bluetooth.a2dpsink; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static org.mockito.Mockito.verify; @@ -29,11 +30,9 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; public class A2dpSinkServiceBinderTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private A2dpSinkService mService; private A2dpSinkService.A2dpSinkServiceBinder mBinder; diff --git a/android/app/tests/unit/src/com/android/bluetooth/a2dpsink/A2dpSinkServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/a2dpsink/A2dpSinkServiceTest.java index 3a7ef9fd54..1cf984a666 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/a2dpsink/A2dpSinkServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/a2dpsink/A2dpSinkServiceTest.java @@ -21,6 +21,7 @@ import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_UNKNOWN; import static android.bluetooth.BluetoothProfile.STATE_CONNECTED; import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTED; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.google.common.truth.Truth.assertThat; @@ -49,8 +50,6 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.util.ArrayList; import java.util.List; @@ -58,7 +57,7 @@ import java.util.List; @MediumTest @RunWith(AndroidJUnit4.class) public class A2dpSinkServiceTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private AdapterService mAdapterService; @Mock private DatabaseManager mDatabaseManager; diff --git a/android/app/tests/unit/src/com/android/bluetooth/a2dpsink/A2dpSinkStateMachineTest.java b/android/app/tests/unit/src/com/android/bluetooth/a2dpsink/A2dpSinkStateMachineTest.java index c77b2287b2..21dc3d7f34 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/a2dpsink/A2dpSinkStateMachineTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/a2dpsink/A2dpSinkStateMachineTest.java @@ -20,6 +20,7 @@ import static android.bluetooth.BluetoothProfile.STATE_CONNECTING; import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTED; import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTING; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.google.common.truth.Truth.assertThat; @@ -44,12 +45,10 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; @RunWith(AndroidJUnit4.class) public class A2dpSinkStateMachineTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private A2dpSinkService mService; @Mock private A2dpSinkNativeInterface mNativeInterface; diff --git a/android/app/tests/unit/src/com/android/bluetooth/a2dpsink/A2dpSinkStreamHandlerTest.java b/android/app/tests/unit/src/com/android/bluetooth/a2dpsink/A2dpSinkStreamHandlerTest.java index a798ced84d..78b73a8e79 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/a2dpsink/A2dpSinkStreamHandlerTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/a2dpsink/A2dpSinkStreamHandlerTest.java @@ -16,6 +16,7 @@ package com.android.bluetooth.a2dpsink; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.mockGetSystemService; import static com.google.common.truth.Truth.assertThat; @@ -47,13 +48,11 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; @MediumTest @RunWith(AndroidJUnit4.class) public class A2dpSinkStreamHandlerTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Rule public final ServiceTestRule mBluetoothBrowserMediaServiceTestRule = new ServiceTestRule(); diff --git a/android/app/tests/unit/src/com/android/bluetooth/audio_util/BrowsablePlayerConnectorTest.java b/android/app/tests/unit/src/com/android/bluetooth/audio_util/BrowsablePlayerConnectorTest.java index b7bc05c113..ab08c8bafc 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/audio_util/BrowsablePlayerConnectorTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/audio_util/BrowsablePlayerConnectorTest.java @@ -16,6 +16,8 @@ package com.android.bluetooth.audio_util; +import static com.android.bluetooth.TestUtils.MockitoRule; + import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; @@ -38,8 +40,6 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.util.ArrayList; import java.util.Collections; @@ -54,7 +54,7 @@ public final class BrowsablePlayerConnectorTest { Context mContext; TestLooper mTestLooper; List<ResolveInfo> mPlayerList; - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock MediaBrowser mMediaBrowser; MediaBrowser.ConnectionCallback mConnectionCallback; diff --git a/android/app/tests/unit/src/com/android/bluetooth/audio_util/BrowserPlayerWrapperTest.java b/android/app/tests/unit/src/com/android/bluetooth/audio_util/BrowserPlayerWrapperTest.java index 3324da491e..94c59c7424 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/audio_util/BrowserPlayerWrapperTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/audio_util/BrowserPlayerWrapperTest.java @@ -16,6 +16,8 @@ package com.android.bluetooth.audio_util; +import static com.android.bluetooth.TestUtils.MockitoRule; + import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.*; @@ -50,8 +52,6 @@ import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Captor; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.io.InputStream; import java.util.ArrayList; @@ -66,7 +66,7 @@ public class BrowserPlayerWrapperTest { @Captor ArgumentCaptor<MediaController.Callback> mControllerCb; @Captor ArgumentCaptor<Handler> mTimeoutHandler; @Captor ArgumentCaptor<List<ListItem>> mWrapperBrowseCb; - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock MediaBrowser mMockBrowser; @Mock BrowsedPlayerWrapper.ConnectionCallback mConnCb; diff --git a/android/app/tests/unit/src/com/android/bluetooth/audio_util/ImageTest.java b/android/app/tests/unit/src/com/android/bluetooth/audio_util/ImageTest.java index 8184081785..cfb35313b8 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/audio_util/ImageTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/audio_util/ImageTest.java @@ -16,6 +16,8 @@ package com.android.bluetooth.audio_util; +import static com.android.bluetooth.TestUtils.MockitoRule; + import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.when; @@ -44,8 +46,6 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.io.InputStream; @@ -53,7 +53,7 @@ import java.io.InputStream; public class ImageTest { private Context mTargetContext; - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); private @Mock Context mMockContext; private Resources mTestResources; diff --git a/android/app/tests/unit/src/com/android/bluetooth/audio_util/MediaPlayerListTest.java b/android/app/tests/unit/src/com/android/bluetooth/audio_util/MediaPlayerListTest.java index 634d7c46d6..3f689acd70 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/audio_util/MediaPlayerListTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/audio_util/MediaPlayerListTest.java @@ -16,6 +16,9 @@ package com.android.bluetooth.audio_util; +import static com.android.bluetooth.TestUtils.MockitoRule; +import static com.android.bluetooth.TestUtils.mockGetSystemService; + import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.*; @@ -40,8 +43,6 @@ import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Captor; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.util.ArrayList; @@ -52,7 +53,7 @@ public class MediaPlayerListTest { private @Captor ArgumentCaptor<MediaPlayerWrapper.Callback> mPlayerWrapperCb; private @Captor ArgumentCaptor<MediaData> mMediaUpdateData; - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); private @Mock Context mMockContext; private @Mock MediaPlayerList.MediaUpdateCallback mMediaUpdateCallback; @@ -73,11 +74,6 @@ public class MediaPlayerListTest { Looper.prepare(); } - AudioManager mockAudioManager = mock(AudioManager.class); - when(mMockContext.getSystemService(Context.AUDIO_SERVICE)).thenReturn(mockAudioManager); - when(mMockContext.getSystemServiceName(AudioManager.class)) - .thenReturn(Context.AUDIO_SERVICE); - // MediaSessionManager is final and Bluetooth can't use extended Mockito to mock it. Thus, // using this as is risks leaking device state into the tests. To avoid this, the injected // controller and player below in the factory pattern will essentially replace each found @@ -87,10 +83,12 @@ public class MediaPlayerListTest { .getTargetContext() .getSystemService(MediaSessionManager.class); PackageManager mockPackageManager = mock(PackageManager.class); - when(mMockContext.getSystemService(Context.MEDIA_SESSION_SERVICE)) - .thenReturn(mMediaSessionManager); - when(mMockContext.getSystemServiceName(MediaSessionManager.class)) - .thenReturn(Context.MEDIA_SESSION_SERVICE); + mockGetSystemService( + mMockContext, + Context.MEDIA_SESSION_SERVICE, + MediaSessionManager.class, + mMediaSessionManager); + mockGetSystemService(mMockContext, Context.AUDIO_SERVICE, AudioManager.class); when(mMockContext.registerReceiver(any(), any())).thenReturn(null); when(mMockContext.getApplicationContext()).thenReturn(mMockContext); diff --git a/android/app/tests/unit/src/com/android/bluetooth/audio_util/MediaPlayerWrapperTest.java b/android/app/tests/unit/src/com/android/bluetooth/audio_util/MediaPlayerWrapperTest.java index 4427bb001f..20784033c2 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/audio_util/MediaPlayerWrapperTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/audio_util/MediaPlayerWrapperTest.java @@ -16,6 +16,8 @@ package com.android.bluetooth.audio_util; +import static com.android.bluetooth.TestUtils.MockitoRule; + import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.*; @@ -30,7 +32,6 @@ import android.media.session.MediaSession; import android.media.session.PlaybackState; import android.os.HandlerThread; import android.os.TestLooperManager; -import android.util.Log; import androidx.test.filters.SmallTest; import androidx.test.platform.app.InstrumentationRegistry; @@ -46,8 +47,6 @@ import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Captor; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.io.InputStream; import java.util.ArrayList; @@ -69,7 +68,7 @@ public class MediaPlayerWrapperTest { @Captor ArgumentCaptor<MediaController.Callback> mControllerCbs; @Captor ArgumentCaptor<MediaData> mMediaUpdateData; - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock MediaController mMockController; @Mock MediaPlayerWrapper.Callback mTestCbs; diff --git a/android/app/tests/unit/src/com/android/bluetooth/audio_util/MetadataTest.java b/android/app/tests/unit/src/com/android/bluetooth/audio_util/MetadataTest.java index 8dbf0c6cc3..d7f7cb56cc 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/audio_util/MetadataTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/audio_util/MetadataTest.java @@ -16,6 +16,8 @@ package com.android.bluetooth.audio_util; +import static com.android.bluetooth.TestUtils.MockitoRule; + import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.when; @@ -46,8 +48,6 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.io.InputStream; @@ -55,7 +55,7 @@ import java.io.InputStream; public class MetadataTest { private Context mTargetContext; - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); private @Mock Context mMockContext; private Resources mTestResources; diff --git a/android/app/tests/unit/src/com/android/bluetooth/avrcp/AvrcpTargetServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/avrcp/AvrcpTargetServiceTest.java index 727b5729ff..c8833de7f1 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/avrcp/AvrcpTargetServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/avrcp/AvrcpTargetServiceTest.java @@ -16,6 +16,9 @@ package com.android.bluetooth.avrcp; +import static com.android.bluetooth.TestUtils.MockitoRule; +import static com.android.bluetooth.TestUtils.mockGetSystemService; + import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.anyInt; @@ -38,7 +41,6 @@ import androidx.test.platform.app.InstrumentationRegistry; import androidx.test.runner.AndroidJUnit4; import com.android.bluetooth.TestLooper; -import com.android.bluetooth.TestUtils; import com.android.bluetooth.audio_util.Image; import com.android.bluetooth.audio_util.Metadata; import com.android.bluetooth.btservice.AdapterService; @@ -51,8 +53,6 @@ import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Captor; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.util.ArrayList; import java.util.List; @@ -60,41 +60,35 @@ import java.util.List; @SmallTest @RunWith(AndroidJUnit4.class) public class AvrcpTargetServiceTest { + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Mock private AdapterService mMockAdapterService; + @Mock private AudioManager mMockAudioManager; + @Mock private AvrcpNativeInterface mMockNativeInterface; + @Mock private Resources mMockResources; + @Mock private SharedPreferences mMockSharedPreferences; + @Mock private SharedPreferences.Editor mMockSharedPreferencesEditor; - private @Mock AdapterService mMockAdapterService; - private @Mock AudioManager mMockAudioManager; - private @Mock AvrcpNativeInterface mMockNativeInterface; - private @Mock UserManager mMockUserManager; - private @Mock Resources mMockResources; - private @Mock SharedPreferences mMockSharedPreferences; - private @Mock SharedPreferences.Editor mMockSharedPreferencesEditor; + @Captor private ArgumentCaptor<AudioDeviceCallback> mAudioDeviceCb; - private @Captor ArgumentCaptor<AudioDeviceCallback> mAudioDeviceCb; + private static final String TEST_DATA = "-1"; - private MediaSessionManager mMediaSessionManager; - private TestLooper mLooper; + private final MediaSessionManager mMediaSessionManager = + InstrumentationRegistry.getInstrumentation() + .getTargetContext() + .getSystemService(MediaSessionManager.class); - private static final String TEST_DATA = "-1"; + private TestLooper mLooper; @Before public void setUp() throws Exception { mLooper = new TestLooper(); mLooper.startAutoDispatch(); - doReturn(mMockAudioManager) - .when(mMockAdapterService) - .getSystemService(Context.AUDIO_SERVICE); - doReturn(Context.AUDIO_SERVICE) - .when(mMockAdapterService) - .getSystemServiceName(AudioManager.class); + mockGetSystemService( + mMockAdapterService, Context.AUDIO_SERVICE, AudioManager.class, mMockAudioManager); - mMediaSessionManager = - InstrumentationRegistry.getInstrumentation() - .getTargetContext() - .getSystemService(MediaSessionManager.class); - TestUtils.mockGetSystemService( + mockGetSystemService( mMockAdapterService, Context.MEDIA_SESSION_SERVICE, MediaSessionManager.class, @@ -103,8 +97,7 @@ public class AvrcpTargetServiceTest { doReturn(mLooper.getNewExecutor()).when(mMockAdapterService).getMainExecutor(); doReturn(mMockAdapterService).when(mMockAdapterService).getApplicationContext(); - TestUtils.mockGetSystemService( - mMockAdapterService, Context.USER_SERVICE, UserManager.class, mMockUserManager); + mockGetSystemService(mMockAdapterService, Context.USER_SERVICE, UserManager.class); doReturn(mMockResources).when(mMockAdapterService).getResources(); doReturn(mMockSharedPreferencesEditor).when(mMockSharedPreferences).edit(); @@ -168,7 +161,6 @@ public class AvrcpTargetServiceTest { volumeManager, mLooper.getLooper()); - service.start(); verify(mMockAudioManager) .registerAudioDeviceCallback(mAudioDeviceCb.capture(), anyObject()); diff --git a/android/app/tests/unit/src/com/android/bluetooth/avrcp/AvrcpVolumeManagerTest.java b/android/app/tests/unit/src/com/android/bluetooth/avrcp/AvrcpVolumeManagerTest.java index c0f9d7cada..f1e54d5cd2 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/avrcp/AvrcpVolumeManagerTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/avrcp/AvrcpVolumeManagerTest.java @@ -16,6 +16,7 @@ package com.android.bluetooth.avrcp; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.android.bluetooth.avrcp.AvrcpVolumeManager.AVRCP_MAX_VOL; @@ -45,13 +46,11 @@ import org.junit.Test; import org.junit.rules.TestName; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; @SmallTest @RunWith(AndroidJUnit4.class) public class AvrcpVolumeManagerTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Rule public TestName testName = new TestName(); @Mock private AvrcpNativeInterface mNativeInterface; diff --git a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpBipClientTest.java b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpBipClientTest.java index cd425ca75a..d4213b5b9f 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpBipClientTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpBipClientTest.java @@ -16,6 +16,7 @@ package com.android.bluetooth.avrcpcontroller; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.google.common.truth.Truth.assertThat; @@ -38,8 +39,6 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; @SmallTest @RunWith(AndroidJUnit4.class) @@ -49,7 +48,7 @@ public class AvrcpBipClientTest { @Rule public final ServiceTestRule mBluetoothBrowserMediaServiceTestRule = new ServiceTestRule(); - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private AvrcpControllerService mService; @Mock private AvrcpCoverArtManager.Callback mCallback; diff --git a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerServiceBinderTest.java b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerServiceBinderTest.java index 25dc10b80f..ac5c5dce3d 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerServiceBinderTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerServiceBinderTest.java @@ -16,6 +16,7 @@ package com.android.bluetooth.avrcpcontroller; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static org.mockito.Mockito.verify; @@ -31,13 +32,11 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; @SmallTest @RunWith(AndroidJUnit4.class) public class AvrcpControllerServiceBinderTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private AvrcpControllerService mService; diff --git a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerServiceTest.java index b45860086e..c1fe79b98b 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerServiceTest.java @@ -15,6 +15,7 @@ */ package com.android.bluetooth.avrcpcontroller; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.android.bluetooth.TestUtils.mockGetSystemService; @@ -54,8 +55,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.util.ArrayList; import java.util.Arrays; @@ -69,7 +68,7 @@ public class AvrcpControllerServiceTest { @Rule public final ServiceTestRule mBluetoothBrowserMediaServiceTestRule = new ServiceTestRule(); - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private A2dpSinkService mA2dpSinkService; @Mock private AdapterService mAdapterService; diff --git a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerStateMachineTest.java b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerStateMachineTest.java index 6c6397e952..633cb43668 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerStateMachineTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerStateMachineTest.java @@ -17,7 +17,9 @@ package com.android.bluetooth.avrcpcontroller; import static android.Manifest.permission.BLUETOOTH_CONNECT; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; +import static com.android.bluetooth.TestUtils.mockGetSystemService; import static com.android.bluetooth.Utils.getBytesFromAddress; import static com.google.common.truth.Truth.assertThat; @@ -59,8 +61,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.util.ArrayList; import java.util.List; @@ -74,7 +74,7 @@ public class AvrcpControllerStateMachineTest { @Rule public final ServiceTestRule mBluetoothBrowserMediaServiceTestRule = new ServiceTestRule(); - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private AdapterService mAdapterService; @Mock private A2dpSinkService mA2dpSinkService; @@ -114,12 +114,8 @@ public class AvrcpControllerStateMachineTest { doReturn(mMockResources).when(mAvrcpControllerService).getResources(); doReturn(mBrowseTree).when(mAvrcpControllerService).getBrowseTree(); - doReturn(mAudioManager) - .when(mAvrcpControllerService) - .getSystemService(Context.AUDIO_SERVICE); - doReturn(Context.AUDIO_SERVICE) - .when(mAvrcpControllerService) - .getSystemServiceName(AudioManager.class); + mockGetSystemService( + mAvrcpControllerService, Context.AUDIO_SERVICE, AudioManager.class, mAudioManager); doReturn(mCoverArtManager).when(mAvrcpControllerService).getCoverArtManager(); if (Looper.myLooper() == null) { Looper.prepare(); diff --git a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtProviderTest.java b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtProviderTest.java index 93a3373ad5..02b563adbf 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtProviderTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtProviderTest.java @@ -16,6 +16,7 @@ package com.android.bluetooth.avrcpcontroller; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.google.common.truth.Truth.assertThat; @@ -34,15 +35,13 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.io.FileNotFoundException; @SmallTest @RunWith(AndroidJUnit4.class) public class AvrcpCoverArtProviderTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private Uri mUri; diff --git a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpPlayerTest.java b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpPlayerTest.java index efd3b5bad9..580de97ba5 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpPlayerTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpPlayerTest.java @@ -16,6 +16,7 @@ package com.android.bluetooth.avrcpcontroller; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.google.common.truth.Truth.assertThat; @@ -29,11 +30,9 @@ import android.support.v4.media.session.PlaybackStateCompat; import org.junit.Rule; import org.junit.Test; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; public class AvrcpPlayerTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private PlayerApplicationSettings mPlayerApplicationSettings; diff --git a/android/app/tests/unit/src/com/android/bluetooth/bas/BatteryServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/bas/BatteryServiceTest.java index fe07e8bbd6..081c4d9204 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/bas/BatteryServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/bas/BatteryServiceTest.java @@ -24,6 +24,7 @@ import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_FORBIDDEN; import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_UNKNOWN; import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTED; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.google.common.truth.Truth.assertThat; @@ -49,15 +50,13 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.util.List; @MediumTest @RunWith(JUnit4.class) public class BatteryServiceTest { - @Rule public final MockitoRule mockito = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private AdapterService mAdapterService; @Mock private DatabaseManager mDatabaseManager; diff --git a/android/app/tests/unit/src/com/android/bluetooth/bas/BatteryStateMachineTest.java b/android/app/tests/unit/src/com/android/bluetooth/bas/BatteryStateMachineTest.java index 0c4fe5552f..cf24333f8f 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/bas/BatteryStateMachineTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/bas/BatteryStateMachineTest.java @@ -21,6 +21,7 @@ import static android.bluetooth.BluetoothProfile.STATE_CONNECTED; import static android.bluetooth.BluetoothProfile.STATE_CONNECTING; import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTED; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.android.bluetooth.bas.BatteryStateMachine.MESSAGE_CONNECT; import static com.android.bluetooth.bas.BatteryStateMachine.MESSAGE_CONNECTION_STATE_CHANGED; @@ -48,13 +49,11 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; @SmallTest @RunWith(JUnit4.class) public class BatteryStateMachineTest { - @Rule public final MockitoRule mockito = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private BatteryService mBatteryService; diff --git a/android/app/tests/unit/src/com/android/bluetooth/bass_client/BassClientServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/bass_client/BassClientServiceTest.java index e299fc383d..d2eaa76b1e 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/bass_client/BassClientServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/bass_client/BassClientServiceTest.java @@ -25,6 +25,7 @@ import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTED; import static androidx.test.espresso.intent.matcher.IntentMatchers.hasAction; import static androidx.test.espresso.intent.matcher.IntentMatchers.hasExtra; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.google.common.truth.Truth.assertThat; @@ -110,8 +111,6 @@ import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.Spy; import org.mockito.hamcrest.MockitoHamcrest; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.util.ArrayList; import java.util.Arrays; @@ -125,7 +124,7 @@ import java.util.stream.Collectors; @MediumTest @RunWith(AndroidJUnit4.class) public class BassClientServiceTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Rule public Expect expect = Expect.create(); @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); @@ -793,6 +792,7 @@ public class BassClientServiceTest { .verify(mMethodProxy) .periodicAdvertisingManagerRegisterSync( any(), any(), anyInt(), anyInt(), any(), any()); + onSyncEstablished(mSourceDevice, TEST_SYNC_HANDLE); // Stop searching mBassClientService.stopSearchingForSources(); @@ -2346,12 +2346,19 @@ public class BassClientServiceTest { TestUtils.waitForLooperToFinishScheduledTask(mBassClientService.getCallbacks().getLooper()); assertThat(mStateMachines).hasSize(2); for (BassClientStateMachine sm : mStateMachines.values()) { - BluetoothDevice dev = sm.getDevice(); - verify(mCallback) - .onSourceModifyFailed( - eq(dev), - eq(TEST_SOURCE_ID), - eq(BluetoothStatusCodes.ERROR_BAD_PARAMETERS)); + if (sm.getDevice().equals(mCurrentDevice)) { + verify(mCallback) + .onSourceModifyFailed( + eq(sm.getDevice()), + eq(TEST_SOURCE_ID), + eq(BluetoothStatusCodes.ERROR_BAD_PARAMETERS)); + } else if (sm.getDevice().equals(mCurrentDevice1)) { + verify(mCallback) + .onSourceModifyFailed( + eq(sm.getDevice()), + eq(TEST_SOURCE_ID + 1), + eq(BluetoothStatusCodes.ERROR_BAD_PARAMETERS)); + } } assertThat(mStateMachines).hasSize(2); @@ -3576,9 +3583,9 @@ public class BassClientServiceTest { generateScanResult(scanResult7); // Increase priority of last 3 of them - mBassClientService.addSelectSourceRequest(broadcastId5, true); - mBassClientService.addSelectSourceRequest(broadcastId6, true); - mBassClientService.addSelectSourceRequest(broadcastId7, true); + mBassClientService.addSelectSourceRequest(broadcastId5, /* hasPriority= */ true); + mBassClientService.addSelectSourceRequest(broadcastId6, /* hasPriority= */ true); + mBassClientService.addSelectSourceRequest(broadcastId7, /* hasPriority= */ true); ArgumentCaptor<ScanResult> resultCaptor = ArgumentCaptor.forClass(ScanResult.class); mInOrderMethodProxy @@ -3851,6 +3858,9 @@ public class BassClientServiceTest { .get(BassConstants.BAAS_UUID))) .isEqualTo(broadcastId2); onSyncLost(); + if (Flags.leaudioBroadcastResyncHelper()) { + checkAndDispatchTimeout(broadcastId1, BassClientService.MESSAGE_SYNC_LOST_TIMEOUT); + } // Added to queue again, high rssi generateScanResult(scanResult1); @@ -3939,11 +3949,11 @@ public class BassClientServiceTest { // mock the update in selectSource mBassClientService.updateSyncHandleForBroadcastId( - BassConstants.INVALID_SYNC_HANDLE, testBroadcastId); + BassConstants.PENDING_SYNC_HANDLE, testBroadcastId); mBassClientService.updatePeriodicAdvertisementResultMap( mSourceDevice, mSourceDevice.getAddressType(), - BassConstants.INVALID_SYNC_HANDLE, + BassConstants.PENDING_SYNC_HANDLE, BassConstants.INVALID_ADV_SID, testAdvInterval, testBroadcastId, @@ -3995,11 +4005,11 @@ public class BassClientServiceTest { // mock the update in selectSource mBassClientService.updateSyncHandleForBroadcastId( - BassConstants.INVALID_SYNC_HANDLE, testBroadcastId1); + BassConstants.PENDING_SYNC_HANDLE, testBroadcastId1); mBassClientService.updatePeriodicAdvertisementResultMap( mSourceDevice, mSourceDevice.getAddressType(), - BassConstants.INVALID_SYNC_HANDLE, + BassConstants.PENDING_SYNC_HANDLE, BassConstants.INVALID_ADV_SID, testAdvInterval1, testBroadcastId1, @@ -4031,11 +4041,11 @@ public class BassClientServiceTest { // mock the update in selectSource mBassClientService.updateSyncHandleForBroadcastId( - BassConstants.INVALID_SYNC_HANDLE, testBroadcastId2); + BassConstants.PENDING_SYNC_HANDLE, testBroadcastId2); mBassClientService.updatePeriodicAdvertisementResultMap( mSourceDevice, mSourceDevice.getAddressType(), - BassConstants.INVALID_SYNC_HANDLE, + BassConstants.PENDING_SYNC_HANDLE, BassConstants.INVALID_ADV_SID, testAdvInterval2, testBroadcastId2, @@ -4100,7 +4110,7 @@ public class BassClientServiceTest { mBassClientService.updatePeriodicAdvertisementResultMap( mSourceDevice, mSourceDevice.getAddressType(), - BassConstants.INVALID_SYNC_HANDLE, + BassConstants.PENDING_SYNC_HANDLE, BassConstants.INVALID_ADV_SID, testAdvInterval, testBroadcastId, @@ -4255,7 +4265,8 @@ public class BassClientServiceTest { // Update receiver state with lost BIS sync injectRemoteSourceStateChanged(meta, true, false); - if (!Flags.leaudioBroadcastResyncHelper()) { + if (!Flags.leaudioBroadcastResyncHelper() + && !Flags.leaudioMonitorUnicastSourceWhenManagedByBroadcastDelegator()) { verify(mLeAudioService).activeBroadcastAssistantNotification(eq(false)); } } @@ -6257,6 +6268,7 @@ public class BassClientServiceTest { Flags.FLAG_LEAUDIO_BROADCAST_RESYNC_HELPER, Flags.FLAG_LEAUDIO_BROADCAST_EXTRACT_PERIODIC_SCANNER_FROM_STATE_MACHINE }) + @DisableFlags(Flags.FLAG_LEAUDIO_BROADCAST_PREVENT_RESUME_INTERRUPTION) public void sinkUnintentional_autoSyncToBroadcast_onStopSearching() { sinkUnintentionalDuringScanning(); @@ -6274,6 +6286,669 @@ public class BassClientServiceTest { @Test @EnableFlags({ Flags.FLAG_LEAUDIO_BROADCAST_RESYNC_HELPER, + Flags.FLAG_LEAUDIO_BROADCAST_EXTRACT_PERIODIC_SCANNER_FROM_STATE_MACHINE, + Flags.FLAG_LEAUDIO_BROADCAST_PREVENT_RESUME_INTERRUPTION + }) + public void sinkUnintentional_remainEstablishedSync_onStopSearching() { + sinkUnintentionalDuringScanning(); + + // Scan and sync to another broadcaster + onScanResult(mSourceDevice2, TEST_BROADCAST_ID + 1); + mInOrderMethodProxy + .verify(mMethodProxy) + .periodicAdvertisingManagerRegisterSync( + any(), any(), anyInt(), anyInt(), any(), any()); + onSyncEstablished(mSourceDevice2, TEST_SYNC_HANDLE + 1); + + // Scan and add add sync to pending + final BluetoothDevice sourceDevice3 = + mBluetoothAdapter.getRemoteLeDevice( + "00:11:22:33:44:11", BluetoothDevice.ADDRESS_TYPE_RANDOM); + onScanResult(sourceDevice3, TEST_BROADCAST_ID + 2); + mInOrderMethodProxy + .verify(mMethodProxy) + .periodicAdvertisingManagerRegisterSync( + any(), any(), anyInt(), anyInt(), any(), any()); + + assertThat(mBassClientService.getActiveSyncedSources().size()).isEqualTo(2); + assertThat(mBassClientService.getActiveSyncedSources()) + .containsExactly(TEST_SYNC_HANDLE, TEST_SYNC_HANDLE + 1); + assertThat(mBassClientService.getDeviceForSyncHandle(TEST_SYNC_HANDLE)) + .isEqualTo(mSourceDevice); + assertThat(mBassClientService.getDeviceForSyncHandle(TEST_SYNC_HANDLE + 1)) + .isEqualTo(mSourceDevice2); + assertThat(mBassClientService.getDeviceForSyncHandle(BassConstants.PENDING_SYNC_HANDLE)) + .isEqualTo(sourceDevice3); + assertThat(mBassClientService.getBroadcastIdForSyncHandle(TEST_SYNC_HANDLE)) + .isEqualTo(TEST_BROADCAST_ID); + assertThat(mBassClientService.getBroadcastIdForSyncHandle(TEST_SYNC_HANDLE + 1)) + .isEqualTo(TEST_BROADCAST_ID + 1); + assertThat( + mBassClientService.getBroadcastIdForSyncHandle( + BassConstants.PENDING_SYNC_HANDLE)) + .isEqualTo(TEST_BROADCAST_ID + 2); + + // Verify that stop searching remain the unintentional sync + mBassClientService.stopSearchingForSources(); + // Unintentional sync remain, another sync was removed, pending was canceled + assertThat(mBassClientService.getActiveSyncedSources().size()).isEqualTo(1); + assertThat(mBassClientService.getActiveSyncedSources()).containsExactly(TEST_SYNC_HANDLE); + assertThat(mBassClientService.getDeviceForSyncHandle(TEST_SYNC_HANDLE)) + .isEqualTo(mSourceDevice); + assertThat(mBassClientService.getDeviceForSyncHandle(TEST_SYNC_HANDLE + 1)).isNull(); + assertThat(mBassClientService.getDeviceForSyncHandle(BassConstants.PENDING_SYNC_HANDLE)) + .isNull(); + assertThat(mBassClientService.getBroadcastIdForSyncHandle(TEST_SYNC_HANDLE)) + .isEqualTo(TEST_BROADCAST_ID); + assertThat(mBassClientService.getBroadcastIdForSyncHandle(TEST_SYNC_HANDLE + 1)) + .isEqualTo(BassConstants.INVALID_BROADCAST_ID); + assertThat( + mBassClientService.getBroadcastIdForSyncHandle( + BassConstants.PENDING_SYNC_HANDLE)) + .isEqualTo(BassConstants.INVALID_BROADCAST_ID); + + // Resumue without another register sync is possible + mBassClientService.resumeReceiversSourceSynchronization(); + mInOrderMethodProxy + .verify(mMethodProxy, never()) + .periodicAdvertisingManagerRegisterSync( + any(), any(), anyInt(), anyInt(), any(), any()); + BluetoothLeBroadcastMetadata meta = createBroadcastMetadata(TEST_BROADCAST_ID); + verifyAllGroupMembersGettingUpdateOrAddSource(meta); + } + + @Test + @EnableFlags({ + Flags.FLAG_LEAUDIO_BROADCAST_RESYNC_HELPER, + Flags.FLAG_LEAUDIO_BROADCAST_EXTRACT_PERIODIC_SCANNER_FROM_STATE_MACHINE, + Flags.FLAG_LEAUDIO_BROADCAST_PREVENT_RESUME_INTERRUPTION + }) + public void waitingForPast_remainPendingSync_onStopSearching() { + prepareSynchronizedPair(); + + // Scan and sync to another broadcaster + onScanResult(mSourceDevice2, TEST_BROADCAST_ID + 1); + mInOrderMethodProxy + .verify(mMethodProxy) + .periodicAdvertisingManagerRegisterSync( + any(), any(), anyInt(), anyInt(), any(), any()); + onSyncEstablished(mSourceDevice2, TEST_SYNC_HANDLE + 1); + + // Sync lost without triggering timeout to keep cache + onSyncLost(); + + // Sync info request force syncing to broadcaster and add sinks pending for PAST + mBassClientService.syncRequestForPast(mCurrentDevice, TEST_BROADCAST_ID, TEST_SOURCE_ID); + mBassClientService.syncRequestForPast( + mCurrentDevice1, TEST_BROADCAST_ID, TEST_SOURCE_ID + 1); + mInOrderMethodProxy + .verify(mMethodProxy) + .periodicAdvertisingManagerRegisterSync( + any(), any(), anyInt(), anyInt(), any(), any()); + + assertThat(mBassClientService.getActiveSyncedSources().size()).isEqualTo(1); + assertThat(mBassClientService.getActiveSyncedSources()) + .containsExactly(TEST_SYNC_HANDLE + 1); + assertThat(mBassClientService.getDeviceForSyncHandle(TEST_SYNC_HANDLE)).isNull(); + assertThat(mBassClientService.getDeviceForSyncHandle(TEST_SYNC_HANDLE + 1)) + .isEqualTo(mSourceDevice2); + assertThat(mBassClientService.getDeviceForSyncHandle(BassConstants.PENDING_SYNC_HANDLE)) + .isEqualTo(mSourceDevice); + assertThat(mBassClientService.getBroadcastIdForSyncHandle(TEST_SYNC_HANDLE)) + .isEqualTo(BassConstants.INVALID_BROADCAST_ID); + assertThat(mBassClientService.getBroadcastIdForSyncHandle(TEST_SYNC_HANDLE + 1)) + .isEqualTo(TEST_BROADCAST_ID + 1); + assertThat( + mBassClientService.getBroadcastIdForSyncHandle( + BassConstants.PENDING_SYNC_HANDLE)) + .isEqualTo(TEST_BROADCAST_ID); + + // Verify that stop searching remain the pending sync + mBassClientService.stopSearchingForSources(); + // Pending remain, another unsynced + assertThat(mBassClientService.getActiveSyncedSources().size()).isEqualTo(0); + assertThat(mBassClientService.getDeviceForSyncHandle(TEST_SYNC_HANDLE)).isNull(); + assertThat(mBassClientService.getDeviceForSyncHandle(TEST_SYNC_HANDLE + 1)).isNull(); + assertThat(mBassClientService.getDeviceForSyncHandle(BassConstants.PENDING_SYNC_HANDLE)) + .isEqualTo(mSourceDevice); + assertThat(mBassClientService.getBroadcastIdForSyncHandle(TEST_SYNC_HANDLE)) + .isEqualTo(BassConstants.INVALID_BROADCAST_ID); + assertThat(mBassClientService.getBroadcastIdForSyncHandle(TEST_SYNC_HANDLE + 1)) + .isEqualTo(BassConstants.INVALID_BROADCAST_ID); + assertThat( + mBassClientService.getBroadcastIdForSyncHandle( + BassConstants.PENDING_SYNC_HANDLE)) + .isEqualTo(TEST_BROADCAST_ID); + + // Establishment possible without register sync + onSyncEstablished(mSourceDevice, TEST_SYNC_HANDLE); + verifyInitiatePaSyncTransferAndNoOthers(); + } + + @Test + @EnableFlags({ + Flags.FLAG_LEAUDIO_BROADCAST_RESYNC_HELPER, + Flags.FLAG_LEAUDIO_BROADCAST_EXTRACT_PERIODIC_SCANNER_FROM_STATE_MACHINE, + Flags.FLAG_LEAUDIO_BROADCAST_PREVENT_RESUME_INTERRUPTION + }) + public void pendingSourceToAdd_remainPendingSync_onStopSearching() { + prepareConnectedDeviceGroup(); + startSearchingForSources(); + + // Scan and sync + onScanResult(mSourceDevice, TEST_BROADCAST_ID); + mInOrderMethodProxy + .verify(mMethodProxy) + .periodicAdvertisingManagerRegisterSync( + any(), any(), anyInt(), anyInt(), any(), any()); + onSyncEstablished(mSourceDevice, TEST_SYNC_HANDLE); + + // Scan and sync to another broadcaster + onScanResult(mSourceDevice2, TEST_BROADCAST_ID + 1); + mInOrderMethodProxy + .verify(mMethodProxy) + .periodicAdvertisingManagerRegisterSync( + any(), any(), anyInt(), anyInt(), any(), any()); + onSyncEstablished(mSourceDevice2, TEST_SYNC_HANDLE + 1); + + // Sync lost without triggering timeout to keep cache + onSyncLost(); + + // Add source force syncing to broadcaster and add sinks to pendingSourcesToAdd + BluetoothLeBroadcastMetadata meta = createBroadcastMetadata(TEST_BROADCAST_ID); + mBassClientService.addSource(mCurrentDevice, meta, true); + mInOrderMethodProxy + .verify(mMethodProxy) + .periodicAdvertisingManagerRegisterSync( + any(), any(), anyInt(), anyInt(), any(), any()); + + assertThat(mBassClientService.getActiveSyncedSources().size()).isEqualTo(1); + assertThat(mBassClientService.getActiveSyncedSources()) + .containsExactly(TEST_SYNC_HANDLE + 1); + assertThat(mBassClientService.getDeviceForSyncHandle(TEST_SYNC_HANDLE)).isNull(); + assertThat(mBassClientService.getDeviceForSyncHandle(TEST_SYNC_HANDLE + 1)) + .isEqualTo(mSourceDevice2); + assertThat(mBassClientService.getDeviceForSyncHandle(BassConstants.PENDING_SYNC_HANDLE)) + .isEqualTo(mSourceDevice); + assertThat(mBassClientService.getBroadcastIdForSyncHandle(TEST_SYNC_HANDLE)) + .isEqualTo(BassConstants.INVALID_BROADCAST_ID); + assertThat(mBassClientService.getBroadcastIdForSyncHandle(TEST_SYNC_HANDLE + 1)) + .isEqualTo(TEST_BROADCAST_ID + 1); + assertThat( + mBassClientService.getBroadcastIdForSyncHandle( + BassConstants.PENDING_SYNC_HANDLE)) + .isEqualTo(TEST_BROADCAST_ID); + + // Verify that stop searching remain the pending sync + mBassClientService.stopSearchingForSources(); + // Pending remain, another unsynced + assertThat(mBassClientService.getActiveSyncedSources().size()).isEqualTo(0); + assertThat(mBassClientService.getDeviceForSyncHandle(TEST_SYNC_HANDLE)).isNull(); + assertThat(mBassClientService.getDeviceForSyncHandle(TEST_SYNC_HANDLE + 1)).isNull(); + assertThat(mBassClientService.getDeviceForSyncHandle(BassConstants.PENDING_SYNC_HANDLE)) + .isEqualTo(mSourceDevice); + assertThat(mBassClientService.getBroadcastIdForSyncHandle(TEST_SYNC_HANDLE)) + .isEqualTo(BassConstants.INVALID_BROADCAST_ID); + assertThat(mBassClientService.getBroadcastIdForSyncHandle(TEST_SYNC_HANDLE + 1)) + .isEqualTo(BassConstants.INVALID_BROADCAST_ID); + assertThat( + mBassClientService.getBroadcastIdForSyncHandle( + BassConstants.PENDING_SYNC_HANDLE)) + .isEqualTo(TEST_BROADCAST_ID); + + // Establishment possible without register sync + onSyncEstablished(mSourceDevice, TEST_SYNC_HANDLE); + verifyAllGroupMembersGettingUpdateOrAddSource(meta); + } + + @Test + @EnableFlags({ + Flags.FLAG_LEAUDIO_BROADCAST_RESYNC_HELPER, + Flags.FLAG_LEAUDIO_BROADCAST_EXTRACT_PERIODIC_SCANNER_FROM_STATE_MACHINE, + Flags.FLAG_LEAUDIO_BROADCAST_PREVENT_RESUME_INTERRUPTION + }) + public void alreadySynced_remainSyncAndCache_onStartSearching() { + prepareConnectedDeviceGroup(); + startSearchingForSources(); + + // Scan and sync + onScanResult(mSourceDevice, TEST_BROADCAST_ID); + mInOrderMethodProxy + .verify(mMethodProxy) + .periodicAdvertisingManagerRegisterSync( + any(), any(), anyInt(), anyInt(), any(), any()); + onSyncEstablished(mSourceDevice, TEST_SYNC_HANDLE); + + // Scan and sync to another broadcaster + onScanResult(mSourceDevice2, TEST_BROADCAST_ID + 1); + mInOrderMethodProxy + .verify(mMethodProxy) + .periodicAdvertisingManagerRegisterSync( + any(), any(), anyInt(), anyInt(), any(), any()); + onSyncEstablished(mSourceDevice2, TEST_SYNC_HANDLE + 1); + + // Cancel all syncs by stop searching + mBassClientService.stopSearchingForSources(); + assertThat(mBassClientService.getActiveSyncedSources().size()).isEqualTo(0); + assertThat(mBassClientService.getDeviceForSyncHandle(TEST_SYNC_HANDLE)).isNull(); + assertThat(mBassClientService.getDeviceForSyncHandle(TEST_SYNC_HANDLE + 1)).isNull(); + assertThat(mBassClientService.getBroadcastIdForSyncHandle(TEST_SYNC_HANDLE)) + .isEqualTo(BassConstants.INVALID_BROADCAST_ID); + assertThat(mBassClientService.getBroadcastIdForSyncHandle(TEST_SYNC_HANDLE + 1)) + .isEqualTo(BassConstants.INVALID_BROADCAST_ID); + + // Add source force syncing to broadcaster + // Not finished to not add UNINTENTIONAL_PAUSE or to not unsync + BluetoothLeBroadcastMetadata meta = createBroadcastMetadata(TEST_BROADCAST_ID); + mBassClientService.addSource(mCurrentDevice, meta, true); + mInOrderMethodProxy + .verify(mMethodProxy) + .periodicAdvertisingManagerRegisterSync( + any(), any(), anyInt(), anyInt(), any(), any()); + + // Synced + onSyncEstablished(mSourceDevice, TEST_SYNC_HANDLE); + verifyAllGroupMembersGettingUpdateOrAddSource(meta); + assertThat(mBassClientService.getActiveSyncedSources().size()).isEqualTo(1); + assertThat(mBassClientService.getDeviceForSyncHandle(TEST_SYNC_HANDLE)) + .isEqualTo(mSourceDevice); + assertThat(mBassClientService.getDeviceForSyncHandle(TEST_SYNC_HANDLE + 1)).isNull(); + assertThat(mBassClientService.getBroadcastIdForSyncHandle(TEST_SYNC_HANDLE)) + .isEqualTo(TEST_BROADCAST_ID); + assertThat(mBassClientService.getBroadcastIdForSyncHandle(TEST_SYNC_HANDLE + 1)) + .isEqualTo(BassConstants.INVALID_BROADCAST_ID); + + // Start searching sources remain synced broadcasters and their cache but remove others + startSearchingForSources(); + assertThat(mBassClientService.getActiveSyncedSources().size()).isEqualTo(1); + assertThat(mBassClientService.getDeviceForSyncHandle(TEST_SYNC_HANDLE)) + .isEqualTo(mSourceDevice); + assertThat(mBassClientService.getDeviceForSyncHandle(TEST_SYNC_HANDLE + 1)).isNull(); + assertThat(mBassClientService.getBroadcastIdForSyncHandle(TEST_SYNC_HANDLE)) + .isEqualTo(TEST_BROADCAST_ID); + assertThat(mBassClientService.getBroadcastIdForSyncHandle(TEST_SYNC_HANDLE + 1)) + .isEqualTo(BassConstants.INVALID_BROADCAST_ID); + + // Sync lost without triggering timeout to keep cache + onSyncLost(); + + // Finish adding source without PA and BIS to detect UNINTENTIONAL_PAUSE which will sync + // again. This will confirm that cache is available + prepareRemoteSourceState(meta, false, false); + mInOrderMethodProxy + .verify(mMethodProxy) + .periodicAdvertisingManagerRegisterSync( + any(), any(), anyInt(), anyInt(), any(), any()); + onSyncEstablished(mSourceDevice, TEST_SYNC_HANDLE); + + // Remove source to allow add again + mBassClientService.removeSource(mCurrentDevice, TEST_SOURCE_ID); + verifyRemoveMessageAndInjectSourceRemoval(); + + // Check if cache is NOT remaining for second broadcaster by adding source + BluetoothLeBroadcastMetadata meta2 = createBroadcastMetadata(TEST_BROADCAST_ID + 1); + mBassClientService.addSource(mCurrentDevice, meta2, true); + mInOrderMethodProxy + .verify(mMethodProxy, never()) + .periodicAdvertisingManagerRegisterSync( + any(), any(), anyInt(), anyInt(), any(), any()); + } + + @Test + @EnableFlags({ + Flags.FLAG_LEAUDIO_BROADCAST_RESYNC_HELPER, + Flags.FLAG_LEAUDIO_BROADCAST_EXTRACT_PERIODIC_SCANNER_FROM_STATE_MACHINE, + Flags.FLAG_LEAUDIO_BROADCAST_PREVENT_RESUME_INTERRUPTION + }) + public void alreadySyncedWithSinks_syncAndRemainCache_onStartSearching() { + prepareSynchronizedPair(); + + // Scan and sync to another broadcaster + onScanResult(mSourceDevice2, TEST_BROADCAST_ID + 1); + mInOrderMethodProxy + .verify(mMethodProxy) + .periodicAdvertisingManagerRegisterSync( + any(), any(), anyInt(), anyInt(), any(), any()); + onSyncEstablished(mSourceDevice2, TEST_SYNC_HANDLE + 1); + + // Cancel all syncs by stop searching + mBassClientService.stopSearchingForSources(); + assertThat(mBassClientService.getActiveSyncedSources().size()).isEqualTo(0); + assertThat(mBassClientService.getDeviceForSyncHandle(TEST_SYNC_HANDLE)).isNull(); + assertThat(mBassClientService.getDeviceForSyncHandle(TEST_SYNC_HANDLE + 1)).isNull(); + assertThat(mBassClientService.getBroadcastIdForSyncHandle(TEST_SYNC_HANDLE)) + .isEqualTo(BassConstants.INVALID_BROADCAST_ID); + assertThat(mBassClientService.getBroadcastIdForSyncHandle(TEST_SYNC_HANDLE + 1)) + .isEqualTo(BassConstants.INVALID_BROADCAST_ID); + + // Start searching sources syncs to the broadcasters already synced with sinks + startSearchingForSources(); + mInOrderMethodProxy + .verify(mMethodProxy) + .periodicAdvertisingManagerRegisterSync( + any(), any(), anyInt(), anyInt(), any(), any()); + assertThat(mBassClientService.getActiveSyncedSources().size()).isEqualTo(0); + assertThat(mBassClientService.getDeviceForSyncHandle(BassConstants.PENDING_SYNC_HANDLE)) + .isEqualTo(mSourceDevice); + assertThat(mBassClientService.getDeviceForSyncHandle(TEST_SYNC_HANDLE + 1)).isNull(); + assertThat( + mBassClientService.getBroadcastIdForSyncHandle( + BassConstants.PENDING_SYNC_HANDLE)) + .isEqualTo(TEST_BROADCAST_ID); + assertThat(mBassClientService.getBroadcastIdForSyncHandle(TEST_SYNC_HANDLE + 1)) + .isEqualTo(BassConstants.INVALID_BROADCAST_ID); + + // Synced + onSyncEstablished(mSourceDevice, TEST_SYNC_HANDLE); + assertThat(mBassClientService.getActiveSyncedSources().size()).isEqualTo(1); + assertThat(mBassClientService.getDeviceForSyncHandle(TEST_SYNC_HANDLE)) + .isEqualTo(mSourceDevice); + assertThat(mBassClientService.getDeviceForSyncHandle(TEST_SYNC_HANDLE + 1)).isNull(); + assertThat(mBassClientService.getBroadcastIdForSyncHandle(TEST_SYNC_HANDLE)) + .isEqualTo(TEST_BROADCAST_ID); + assertThat(mBassClientService.getBroadcastIdForSyncHandle(TEST_SYNC_HANDLE + 1)) + .isEqualTo(BassConstants.INVALID_BROADCAST_ID); + + // Sync lost without triggering timeout to keep cache + onSyncLost(); + + // Remove source to allow add again + mBassClientService.removeSource(mCurrentDevice, TEST_SOURCE_ID); + verifyRemoveMessageAndInjectSourceRemoval(); + + // Check if cache is NOT remaining for second broadcaster by adding source + BluetoothLeBroadcastMetadata meta2 = createBroadcastMetadata(TEST_BROADCAST_ID + 1); + mBassClientService.addSource(mCurrentDevice, meta2, true); + mInOrderMethodProxy + .verify(mMethodProxy, never()) + .periodicAdvertisingManagerRegisterSync( + any(), any(), anyInt(), anyInt(), any(), any()); + + // Check if cache is remaining for already synced broadcaster by adding source + BluetoothLeBroadcastMetadata meta = createBroadcastMetadata(TEST_BROADCAST_ID); + mBassClientService.addSource(mCurrentDevice, meta, true); + mInOrderMethodProxy + .verify(mMethodProxy) + .periodicAdvertisingManagerRegisterSync( + any(), any(), anyInt(), anyInt(), any(), any()); + } + + @Test + @EnableFlags({ + Flags.FLAG_LEAUDIO_BROADCAST_RESYNC_HELPER, + Flags.FLAG_LEAUDIO_BROADCAST_EXTRACT_PERIODIC_SCANNER_FROM_STATE_MACHINE, + Flags.FLAG_LEAUDIO_BROADCAST_PREVENT_RESUME_INTERRUPTION + }) + public void waitingForPast_remainPendingSyncAndCache_onStartSearching() { + prepareSynchronizedPair(); + + // Scan and sync to another broadcaster + onScanResult(mSourceDevice2, TEST_BROADCAST_ID + 1); + mInOrderMethodProxy + .verify(mMethodProxy) + .periodicAdvertisingManagerRegisterSync( + any(), any(), anyInt(), anyInt(), any(), any()); + onSyncEstablished(mSourceDevice2, TEST_SYNC_HANDLE + 1); + + // Cancel all syncs by stop searching + mBassClientService.stopSearchingForSources(); + assertThat(mBassClientService.getActiveSyncedSources().size()).isEqualTo(0); + assertThat(mBassClientService.getDeviceForSyncHandle(TEST_SYNC_HANDLE)).isNull(); + assertThat(mBassClientService.getDeviceForSyncHandle(TEST_SYNC_HANDLE + 1)).isNull(); + assertThat(mBassClientService.getBroadcastIdForSyncHandle(TEST_SYNC_HANDLE)) + .isEqualTo(BassConstants.INVALID_BROADCAST_ID); + assertThat(mBassClientService.getBroadcastIdForSyncHandle(TEST_SYNC_HANDLE + 1)) + .isEqualTo(BassConstants.INVALID_BROADCAST_ID); + + // Sync info request force syncing to broadcaster and add sinks pending for PAST + mBassClientService.syncRequestForPast(mCurrentDevice, TEST_BROADCAST_ID, TEST_SOURCE_ID); + mBassClientService.syncRequestForPast( + mCurrentDevice1, TEST_BROADCAST_ID, TEST_SOURCE_ID + 1); + mInOrderMethodProxy + .verify(mMethodProxy) + .periodicAdvertisingManagerRegisterSync( + any(), any(), anyInt(), anyInt(), any(), any()); + + // Start searching sources remain pending sync and cache for broadcaster waiting for past + startSearchingForSources(); + assertThat(mBassClientService.getActiveSyncedSources().size()).isEqualTo(0); + assertThat(mBassClientService.getDeviceForSyncHandle(BassConstants.PENDING_SYNC_HANDLE)) + .isEqualTo(mSourceDevice); + assertThat(mBassClientService.getDeviceForSyncHandle(TEST_SYNC_HANDLE + 1)).isNull(); + assertThat( + mBassClientService.getBroadcastIdForSyncHandle( + BassConstants.PENDING_SYNC_HANDLE)) + .isEqualTo(TEST_BROADCAST_ID); + assertThat(mBassClientService.getBroadcastIdForSyncHandle(TEST_SYNC_HANDLE + 1)) + .isEqualTo(BassConstants.INVALID_BROADCAST_ID); + + // Synced + onSyncEstablished(mSourceDevice, TEST_SYNC_HANDLE); + verifyInitiatePaSyncTransferAndNoOthers(); + assertThat(mBassClientService.getActiveSyncedSources().size()).isEqualTo(1); + assertThat(mBassClientService.getDeviceForSyncHandle(TEST_SYNC_HANDLE)) + .isEqualTo(mSourceDevice); + assertThat(mBassClientService.getDeviceForSyncHandle(TEST_SYNC_HANDLE + 1)).isNull(); + assertThat(mBassClientService.getBroadcastIdForSyncHandle(TEST_SYNC_HANDLE)) + .isEqualTo(TEST_BROADCAST_ID); + assertThat(mBassClientService.getBroadcastIdForSyncHandle(TEST_SYNC_HANDLE + 1)) + .isEqualTo(BassConstants.INVALID_BROADCAST_ID); + + // Sync lost without triggering timeout to keep cache + onSyncLost(); + + // Remove source to allow add again + mBassClientService.removeSource(mCurrentDevice, TEST_SOURCE_ID); + verifyRemoveMessageAndInjectSourceRemoval(); + + // Check if cache is NOT remaining for second broadcaster by adding source + BluetoothLeBroadcastMetadata meta2 = createBroadcastMetadata(TEST_BROADCAST_ID + 1); + mBassClientService.addSource(mCurrentDevice, meta2, true); + mInOrderMethodProxy + .verify(mMethodProxy, never()) + .periodicAdvertisingManagerRegisterSync( + any(), any(), anyInt(), anyInt(), any(), any()); + + // Check if cache is remaining for already synced broadcaster by adding source + BluetoothLeBroadcastMetadata meta = createBroadcastMetadata(TEST_BROADCAST_ID); + mBassClientService.addSource(mCurrentDevice, meta, true); + mInOrderMethodProxy + .verify(mMethodProxy) + .periodicAdvertisingManagerRegisterSync( + any(), any(), anyInt(), anyInt(), any(), any()); + } + + @Test + @EnableFlags({ + Flags.FLAG_LEAUDIO_BROADCAST_RESYNC_HELPER, + Flags.FLAG_LEAUDIO_BROADCAST_EXTRACT_PERIODIC_SCANNER_FROM_STATE_MACHINE, + Flags.FLAG_LEAUDIO_BROADCAST_PREVENT_RESUME_INTERRUPTION + }) + public void pendingSourcesToAdd_remainPendingSyncAndCache_onStartSearching() { + prepareConnectedDeviceGroup(); + startSearchingForSources(); + + // Scan and sync + onScanResult(mSourceDevice, TEST_BROADCAST_ID); + mInOrderMethodProxy + .verify(mMethodProxy) + .periodicAdvertisingManagerRegisterSync( + any(), any(), anyInt(), anyInt(), any(), any()); + onSyncEstablished(mSourceDevice, TEST_SYNC_HANDLE); + + // Scan and sync to another broadcaster + onScanResult(mSourceDevice2, TEST_BROADCAST_ID + 1); + mInOrderMethodProxy + .verify(mMethodProxy) + .periodicAdvertisingManagerRegisterSync( + any(), any(), anyInt(), anyInt(), any(), any()); + onSyncEstablished(mSourceDevice2, TEST_SYNC_HANDLE + 1); + + // Cancel all syncs by stop searching + mBassClientService.stopSearchingForSources(); + assertThat(mBassClientService.getActiveSyncedSources().size()).isEqualTo(0); + assertThat(mBassClientService.getDeviceForSyncHandle(TEST_SYNC_HANDLE)).isNull(); + assertThat(mBassClientService.getDeviceForSyncHandle(TEST_SYNC_HANDLE + 1)).isNull(); + assertThat(mBassClientService.getBroadcastIdForSyncHandle(TEST_SYNC_HANDLE)) + .isEqualTo(BassConstants.INVALID_BROADCAST_ID); + assertThat(mBassClientService.getBroadcastIdForSyncHandle(TEST_SYNC_HANDLE + 1)) + .isEqualTo(BassConstants.INVALID_BROADCAST_ID); + + // Add source force syncing to broadcaster + // Not finished to not add UNINTENTIONAL_PAUSE or to not unsync + BluetoothLeBroadcastMetadata meta = createBroadcastMetadata(TEST_BROADCAST_ID); + mBassClientService.addSource(mCurrentDevice, meta, true); + mInOrderMethodProxy + .verify(mMethodProxy) + .periodicAdvertisingManagerRegisterSync( + any(), any(), anyInt(), anyInt(), any(), any()); + + // Start searching sources remain pending sync and cache for broadcaster + startSearchingForSources(); + assertThat(mBassClientService.getActiveSyncedSources().size()).isEqualTo(0); + assertThat(mBassClientService.getDeviceForSyncHandle(BassConstants.PENDING_SYNC_HANDLE)) + .isEqualTo(mSourceDevice); + assertThat(mBassClientService.getDeviceForSyncHandle(TEST_SYNC_HANDLE + 1)).isNull(); + assertThat( + mBassClientService.getBroadcastIdForSyncHandle( + BassConstants.PENDING_SYNC_HANDLE)) + .isEqualTo(TEST_BROADCAST_ID); + assertThat(mBassClientService.getBroadcastIdForSyncHandle(TEST_SYNC_HANDLE + 1)) + .isEqualTo(BassConstants.INVALID_BROADCAST_ID); + + // Synced + onSyncEstablished(mSourceDevice, TEST_SYNC_HANDLE); + verifyAllGroupMembersGettingUpdateOrAddSource(meta); + assertThat(mBassClientService.getActiveSyncedSources().size()).isEqualTo(1); + assertThat(mBassClientService.getDeviceForSyncHandle(TEST_SYNC_HANDLE)) + .isEqualTo(mSourceDevice); + assertThat(mBassClientService.getDeviceForSyncHandle(TEST_SYNC_HANDLE + 1)).isNull(); + assertThat(mBassClientService.getBroadcastIdForSyncHandle(TEST_SYNC_HANDLE)) + .isEqualTo(TEST_BROADCAST_ID); + assertThat(mBassClientService.getBroadcastIdForSyncHandle(TEST_SYNC_HANDLE + 1)) + .isEqualTo(BassConstants.INVALID_BROADCAST_ID); + + // Sync lost without triggering timeout to keep cache + onSyncLost(); + + // Finish adding source without PA and BIS to detect UNINTENTIONAL_PAUSE which will sync + // again. This will confirm that cache is available + prepareRemoteSourceState(meta, false, false); + mInOrderMethodProxy + .verify(mMethodProxy) + .periodicAdvertisingManagerRegisterSync( + any(), any(), anyInt(), anyInt(), any(), any()); + onSyncEstablished(mSourceDevice, TEST_SYNC_HANDLE); + + // Remove source to allow add again + mBassClientService.removeSource(mCurrentDevice, TEST_SOURCE_ID); + verifyRemoveMessageAndInjectSourceRemoval(); + + // Check if cache is NOT remaining for second broadcaster by adding source + BluetoothLeBroadcastMetadata meta2 = createBroadcastMetadata(TEST_BROADCAST_ID + 1); + mBassClientService.addSource(mCurrentDevice, meta2, true); + mInOrderMethodProxy + .verify(mMethodProxy, never()) + .periodicAdvertisingManagerRegisterSync( + any(), any(), anyInt(), anyInt(), any(), any()); + } + + @Test + @EnableFlags({ + Flags.FLAG_LEAUDIO_BROADCAST_RESYNC_HELPER, + Flags.FLAG_LEAUDIO_BROADCAST_EXTRACT_PERIODIC_SCANNER_FROM_STATE_MACHINE, + Flags.FLAG_LEAUDIO_BROADCAST_PREVENT_RESUME_INTERRUPTION + }) + public void hostIntentional_SyncAndRemainCache_onStartSearching() { + prepareSynchronizedPair(); + + // Scan and sync to another broadcaster + onScanResult(mSourceDevice2, TEST_BROADCAST_ID + 1); + mInOrderMethodProxy + .verify(mMethodProxy) + .periodicAdvertisingManagerRegisterSync( + any(), any(), anyInt(), anyInt(), any(), any()); + onSyncEstablished(mSourceDevice2, TEST_SYNC_HANDLE + 1); + + // Cancel all syncs by stop searching + mBassClientService.stopSearchingForSources(); + assertThat(mBassClientService.getActiveSyncedSources().size()).isEqualTo(0); + assertThat(mBassClientService.getDeviceForSyncHandle(TEST_SYNC_HANDLE)).isNull(); + assertThat(mBassClientService.getDeviceForSyncHandle(TEST_SYNC_HANDLE + 1)).isNull(); + assertThat(mBassClientService.getBroadcastIdForSyncHandle(TEST_SYNC_HANDLE)) + .isEqualTo(BassConstants.INVALID_BROADCAST_ID); + assertThat(mBassClientService.getBroadcastIdForSyncHandle(TEST_SYNC_HANDLE + 1)) + .isEqualTo(BassConstants.INVALID_BROADCAST_ID); + + // Suspend all receivers, HOST_INTENTIONAL + mBassClientService.suspendAllReceiversSourceSynchronization(); + verifyRemoveMessageAndInjectSourceRemoval(); + + // Start searching sources sync to paused broadcaser and remain cache + startSearchingForSources(); + mInOrderMethodProxy + .verify(mMethodProxy) + .periodicAdvertisingManagerRegisterSync( + any(), any(), anyInt(), anyInt(), any(), any()); + assertThat(mBassClientService.getActiveSyncedSources().size()).isEqualTo(0); + assertThat(mBassClientService.getDeviceForSyncHandle(BassConstants.PENDING_SYNC_HANDLE)) + .isEqualTo(mSourceDevice); + assertThat(mBassClientService.getDeviceForSyncHandle(TEST_SYNC_HANDLE + 1)).isNull(); + assertThat( + mBassClientService.getBroadcastIdForSyncHandle( + BassConstants.PENDING_SYNC_HANDLE)) + .isEqualTo(TEST_BROADCAST_ID); + assertThat(mBassClientService.getBroadcastIdForSyncHandle(TEST_SYNC_HANDLE + 1)) + .isEqualTo(BassConstants.INVALID_BROADCAST_ID); + + // Synced + onSyncEstablished(mSourceDevice, TEST_SYNC_HANDLE); + assertThat(mBassClientService.getActiveSyncedSources().size()).isEqualTo(1); + assertThat(mBassClientService.getDeviceForSyncHandle(TEST_SYNC_HANDLE)) + .isEqualTo(mSourceDevice); + assertThat(mBassClientService.getDeviceForSyncHandle(TEST_SYNC_HANDLE + 1)).isNull(); + assertThat(mBassClientService.getBroadcastIdForSyncHandle(TEST_SYNC_HANDLE)) + .isEqualTo(TEST_BROADCAST_ID); + assertThat(mBassClientService.getBroadcastIdForSyncHandle(TEST_SYNC_HANDLE + 1)) + .isEqualTo(BassConstants.INVALID_BROADCAST_ID); + + // Resume broadcast + mBassClientService.resumeReceiversSourceSynchronization(); + mInOrderMethodProxy + .verify(mMethodProxy, never()) + .periodicAdvertisingManagerRegisterSync( + any(), any(), anyInt(), anyInt(), any(), any()); + BluetoothLeBroadcastMetadata meta = createBroadcastMetadata(TEST_BROADCAST_ID); + verifyAllGroupMembersGettingUpdateOrAddSource(meta); + prepareRemoteSourceState(meta, true, true); + + // Sync lost without triggering timeout to keep cache + onSyncLost(); + + // Remove source to allow add again + mBassClientService.removeSource(mCurrentDevice, TEST_SOURCE_ID); + mBassClientService.removeSource(mCurrentDevice1, TEST_SOURCE_ID + 1); + verifyRemoveMessageAndInjectSourceRemoval(); + + // Check if cache is NOT remaining for second broadcaster by adding source + BluetoothLeBroadcastMetadata meta2 = createBroadcastMetadata(TEST_BROADCAST_ID + 1); + mBassClientService.addSource(mCurrentDevice, meta2, true); + mInOrderMethodProxy + .verify(mMethodProxy, never()) + .periodicAdvertisingManagerRegisterSync( + any(), any(), anyInt(), anyInt(), any(), any()); + + // Check if cache is remaining for already synced broadcaster by adding source + mBassClientService.addSource(mCurrentDevice, meta, true); + mInOrderMethodProxy + .verify(mMethodProxy) + .periodicAdvertisingManagerRegisterSync( + any(), any(), anyInt(), anyInt(), any(), any()); + } + + @Test + @EnableFlags({ + Flags.FLAG_LEAUDIO_BROADCAST_RESYNC_HELPER, Flags.FLAG_LEAUDIO_BROADCAST_EXTRACT_PERIODIC_SCANNER_FROM_STATE_MACHINE }) public void hostIntentional_addSameSource() { @@ -6975,6 +7650,641 @@ public class BassClientServiceTest { checkResumeSynchronizationByHost(); } + @Test + @EnableFlags({ + Flags.FLAG_LEAUDIO_BROADCAST_RESYNC_HELPER, + Flags.FLAG_LEAUDIO_BROADCAST_EXTRACT_PERIODIC_SCANNER_FROM_STATE_MACHINE + }) + public void removeSource_duringSuspend() { + prepareSynchronizedPair(); + + // Suspend receivers, HOST_INTENTIONAL + mBassClientService.suspendReceiversSourceSynchronization(TEST_BROADCAST_ID); + + // Remove source, HOST_INTENTIONAL + mBassClientService.removeSource(mCurrentDevice, TEST_SOURCE_ID); + checkNoSinkPause(); + verifyRemoveMessageAndInjectSourceRemoval(); + + checkNoResumeSynchronizationByHost(); + } + + @Test + @EnableFlags({ + Flags.FLAG_LEAUDIO_BROADCAST_RESYNC_HELPER, + Flags.FLAG_LEAUDIO_BROADCAST_EXTRACT_PERIODIC_SCANNER_FROM_STATE_MACHINE + }) + public void stopReceivers_duringSuspend() { + prepareSynchronizedPair(); + + // Suspend receivers, HOST_INTENTIONAL + mBassClientService.suspendReceiversSourceSynchronization(TEST_BROADCAST_ID); + + // Remove source, HOST_INTENTIONAL + mBassClientService.stopReceiversSourceSynchronization(TEST_BROADCAST_ID); + checkNoSinkPause(); + verifyRemoveMessageAndInjectSourceRemoval(); + + checkNoResumeSynchronizationByHost(); + } + + @Test + @EnableFlags({ + Flags.FLAG_LEAUDIO_BROADCAST_RESYNC_HELPER, + Flags.FLAG_LEAUDIO_BROADCAST_EXTRACT_PERIODIC_SCANNER_FROM_STATE_MACHINE + }) + public void multipleSinkMetadata_clearWhenSourceAddFailed() throws RemoteException { + prepareConnectedDeviceGroup(); + startSearchingForSources(); + onScanResult(mSourceDevice, TEST_BROADCAST_ID); + onSyncEstablished(mSourceDevice, TEST_SYNC_HANDLE); + BluetoothLeBroadcastMetadata meta = createBroadcastMetadata(TEST_BROADCAST_ID); + verifyAddSourceForGroup(meta); + prepareRemoteSourceState(meta, true, true); + mBassClientService.stopSearchingForSources(); + prepareRemoteSourceState(meta, false, false); + for (BassClientStateMachine sm : mStateMachines.values()) { + clearInvocations(sm); + } + + // Cache and resume ended with source add failed, should remove metadata + mBassClientService.cacheSuspendingSources(TEST_BROADCAST_ID); + mBassClientService.resumeReceiversSourceSynchronization(); + onSyncEstablishedFailed(mSourceDevice, TEST_SYNC_HANDLE); + TestUtils.waitForLooperToFinishScheduledTask(mBassClientService.getCallbacks().getLooper()); + verify(mCallback).onSourceLost(eq(TEST_BROADCAST_ID)); + verify(mCallback) + .onSourceAddFailed( + eq(mCurrentDevice), + eq(meta), + eq(BluetoothStatusCodes.ERROR_LOCAL_NOT_ENOUGH_RESOURCES)); + verify(mCallback) + .onSourceAddFailed( + eq(mCurrentDevice1), + eq(meta), + eq(BluetoothStatusCodes.ERROR_LOCAL_NOT_ENOUGH_RESOURCES)); + + startSearchingForSources(); + onScanResult(mSourceDevice, TEST_BROADCAST_ID); + onSyncEstablished(mSourceDevice, TEST_SYNC_HANDLE); + + // Cache and resume should not resume at all + mBassClientService.cacheSuspendingSources(TEST_BROADCAST_ID); + mBassClientService.resumeReceiversSourceSynchronization(); + assertThat(mStateMachines.size()).isEqualTo(2); + for (BassClientStateMachine sm : mStateMachines.values()) { + verify(sm, never()).sendMessage(any()); + } + } + + @Test + @EnableFlags({ + Flags.FLAG_LEAUDIO_BROADCAST_RESYNC_HELPER, + Flags.FLAG_LEAUDIO_BROADCAST_EXTRACT_PERIODIC_SCANNER_FROM_STATE_MACHINE + }) + public void multipleSinkMetadata_clearWhenSwitch() { + prepareConnectedDeviceGroup(); + startSearchingForSources(); + onScanResult(mSourceDevice, TEST_BROADCAST_ID); + onSyncEstablished(mSourceDevice, TEST_SYNC_HANDLE); + BluetoothLeBroadcastMetadata meta = createBroadcastMetadata(TEST_BROADCAST_ID); + verifyAddSourceForGroup(meta); + prepareRemoteSourceState(meta, false, false); + + // Add another new broadcast source should remove old metadata during switch + onScanResult(mSourceDevice2, TEST_BROADCAST_ID + 1); + onSyncEstablished(mSourceDevice2, TEST_SYNC_HANDLE + 1); + BluetoothLeBroadcastMetadata newMeta = createBroadcastMetadata(TEST_BROADCAST_ID + 1); + mBassClientService.addSource(mCurrentDevice, newMeta, true); + verifyAllGroupMembersGettingUpdateOrAddSource(newMeta); + for (BassClientStateMachine sm : mStateMachines.values()) { + clearInvocations(sm); + } + prepareRemoteSourceState(newMeta, false, false); + + // Cache and resume should resume only new broadcast + mBassClientService.cacheSuspendingSources(TEST_BROADCAST_ID + 1); + mBassClientService.resumeReceiversSourceSynchronization(); + // Verify that only one message per sink was sent + for (BassClientStateMachine sm : mStateMachines.values()) { + ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class); + verify(sm).sendMessage(messageCaptor.capture()); + } + // And this message is to resume broadcast + verifyAllGroupMembersGettingUpdateOrAddSource(newMeta); + } + + @Test + @EnableFlags({ + Flags.FLAG_LEAUDIO_BROADCAST_RESYNC_HELPER, + Flags.FLAG_LEAUDIO_BROADCAST_EXTRACT_PERIODIC_SCANNER_FROM_STATE_MACHINE + }) + public void multipleSinkMetadata_clearWhenSwitch_duringSuspend() { + prepareConnectedDeviceGroup(); + startSearchingForSources(); + onScanResult(mSourceDevice, TEST_BROADCAST_ID); + onSyncEstablished(mSourceDevice, TEST_SYNC_HANDLE); + BluetoothLeBroadcastMetadata meta = createBroadcastMetadata(TEST_BROADCAST_ID); + verifyAddSourceForGroup(meta); + prepareRemoteSourceState(meta, false, false); + + /* Unicast would like to stream */ + mBassClientService.handleUnicastSourceStreamStatusChange( + 3 /* STATUS_LOCAL_STREAM_REQUESTED_NO_CONTEXT_VALIDATE */); + verifyRemoveMessageAndInjectSourceRemoval(); + for (BassClientStateMachine sm : mStateMachines.values()) { + clearInvocations(sm); + } + + // Add another new broadcast source should remove old metadata + onScanResult(mSourceDevice2, TEST_BROADCAST_ID + 1); + onSyncEstablished(mSourceDevice2, TEST_SYNC_HANDLE + 1); + BluetoothLeBroadcastMetadata newMeta = createBroadcastMetadata(TEST_BROADCAST_ID + 1); + mBassClientService.addSource(mCurrentDevice, newMeta, true); + verifyAllGroupMembersGettingUpdateOrAddSource(newMeta); + for (BassClientStateMachine sm : mStateMachines.values()) { + clearInvocations(sm); + } + prepareRemoteSourceState(newMeta, false, false); + + // Cache and resume should resume only new broadcast + mBassClientService.cacheSuspendingSources(TEST_BROADCAST_ID + 1); + mBassClientService.resumeReceiversSourceSynchronization(); + // Verify that only one message per sink was sent + for (BassClientStateMachine sm : mStateMachines.values()) { + ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class); + verify(sm).sendMessage(messageCaptor.capture()); + } + // And this message is to resume broadcast + verifyAllGroupMembersGettingUpdateOrAddSource(newMeta); + } + + @Test + @EnableFlags({ + Flags.FLAG_LEAUDIO_BROADCAST_RESYNC_HELPER, + Flags.FLAG_LEAUDIO_BROADCAST_EXTRACT_PERIODIC_SCANNER_FROM_STATE_MACHINE + }) + public void multipleSinkMetadata_clearWhenRemove() { + prepareConnectedDeviceGroup(); + startSearchingForSources(); + onScanResult(mSourceDevice, TEST_BROADCAST_ID); + onSyncEstablished(mSourceDevice, TEST_SYNC_HANDLE); + BluetoothLeBroadcastMetadata meta = createBroadcastMetadata(TEST_BROADCAST_ID); + mBassClientService.addSource(mCurrentDevice, meta, false); + mBassClientService.addSource(mCurrentDevice1, meta, false); + for (BassClientStateMachine sm : mStateMachines.values()) { + clearInvocations(sm); + } + prepareRemoteSourceState(meta, false, false); + + // Remove source should remove metadata + // Do not clear receive state + mBassClientService.removeSource(mCurrentDevice, TEST_SOURCE_ID); + for (BassClientStateMachine sm : mStateMachines.values()) { + clearInvocations(sm); + } + + // Cache and resume should resume only one broadcaster + mBassClientService.cacheSuspendingSources(TEST_BROADCAST_ID); + mBassClientService.resumeReceiversSourceSynchronization(); + assertThat(mStateMachines.size()).isEqualTo(2); + for (BassClientStateMachine sm : mStateMachines.values()) { + if (sm.getDevice().equals(mCurrentDevice)) { + verify(sm, never()).sendMessage(any()); + clearInvocations(sm); + } else if (sm.getDevice().equals(mCurrentDevice1)) { + ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class); + verify(sm, atLeast(1)).sendMessage(messageCaptor.capture()); + + Message msg = + messageCaptor.getAllValues().stream() + .filter(m -> (m.what == BassClientStateMachine.UPDATE_BCAST_SOURCE)) + .findFirst() + .orElse(null); + assertThat(msg).isNotNull(); + clearInvocations(sm); + } + } + + // Remove source should remove metadata + // Do not clear receive state + mBassClientService.removeSource(mCurrentDevice1, TEST_SOURCE_ID + 1); + for (BassClientStateMachine sm : mStateMachines.values()) { + clearInvocations(sm); + } + + // Cache and resume should not resume at all + mBassClientService.cacheSuspendingSources(TEST_BROADCAST_ID); + mBassClientService.resumeReceiversSourceSynchronization(); + assertThat(mStateMachines.size()).isEqualTo(2); + for (BassClientStateMachine sm : mStateMachines.values()) { + verify(sm, never()).sendMessage(any()); + } + } + + @Test + @EnableFlags({ + Flags.FLAG_LEAUDIO_BROADCAST_RESYNC_HELPER, + Flags.FLAG_LEAUDIO_BROADCAST_EXTRACT_PERIODIC_SCANNER_FROM_STATE_MACHINE + }) + public void multipleSinkMetadata_clearWhenAllDisconnected() { + prepareConnectedDeviceGroup(); + startSearchingForSources(); + onScanResult(mSourceDevice, TEST_BROADCAST_ID); + onSyncEstablished(mSourceDevice, TEST_SYNC_HANDLE); + BluetoothLeBroadcastMetadata meta = createBroadcastMetadata(TEST_BROADCAST_ID); + verifyAddSourceForGroup(meta); + for (BassClientStateMachine sm : mStateMachines.values()) { + clearInvocations(sm); + } + prepareRemoteSourceState(meta, false, false); + + // Disconnect first sink not cause removing metadata + doReturn(BluetoothProfile.STATE_DISCONNECTED) + .when(mStateMachines.get(mCurrentDevice)) + .getConnectionState(); + doReturn(false).when(mStateMachines.get(mCurrentDevice)).isConnected(); + mBassClientService.connectionStateChanged( + mCurrentDevice, + BluetoothProfile.STATE_CONNECTED, + BluetoothProfile.STATE_DISCONNECTED); + injectRemoteSourceStateRemoval(mStateMachines.get(mCurrentDevice), TEST_SOURCE_ID); + + // Connect again first sink + doReturn(BluetoothProfile.STATE_CONNECTED) + .when(mStateMachines.get(mCurrentDevice)) + .getConnectionState(); + doReturn(true).when(mStateMachines.get(mCurrentDevice)).isConnected(); + prepareRemoteSourceState(meta, false, false); + + // Cache and resume should resume all devices + mBassClientService.cacheSuspendingSources(TEST_BROADCAST_ID); + mBassClientService.resumeReceiversSourceSynchronization(); + verifyAllGroupMembersGettingUpdateOrAddSource(meta); + for (BassClientStateMachine sm : mStateMachines.values()) { + clearInvocations(sm); + } + + // Disconnect first sink not cause removing metadata + doReturn(BluetoothProfile.STATE_DISCONNECTED) + .when(mStateMachines.get(mCurrentDevice)) + .getConnectionState(); + doReturn(false).when(mStateMachines.get(mCurrentDevice)).isConnected(); + mBassClientService.connectionStateChanged( + mCurrentDevice, + BluetoothProfile.STATE_CONNECTED, + BluetoothProfile.STATE_DISCONNECTED); + injectRemoteSourceStateRemoval(mStateMachines.get(mCurrentDevice), TEST_SOURCE_ID); + + // Disconnect second sink cause remove metada for both devices + doReturn(BluetoothProfile.STATE_DISCONNECTED) + .when(mStateMachines.get(mCurrentDevice1)) + .getConnectionState(); + doReturn(false).when(mStateMachines.get(mCurrentDevice1)).isConnected(); + mBassClientService.connectionStateChanged( + mCurrentDevice1, + BluetoothProfile.STATE_CONNECTED, + BluetoothProfile.STATE_DISCONNECTED); + injectRemoteSourceStateRemoval(mStateMachines.get(mCurrentDevice1), TEST_SOURCE_ID + 1); + + // Connect again both devices + doReturn(BluetoothProfile.STATE_CONNECTED) + .when(mStateMachines.get(mCurrentDevice)) + .getConnectionState(); + doReturn(true).when(mStateMachines.get(mCurrentDevice)).isConnected(); + doReturn(BluetoothProfile.STATE_CONNECTED) + .when(mStateMachines.get(mCurrentDevice1)) + .getConnectionState(); + doReturn(true).when(mStateMachines.get(mCurrentDevice1)).isConnected(); + prepareRemoteSourceState(meta, false, false); + + // Cache and resume should not resume at all + mBassClientService.cacheSuspendingSources(TEST_BROADCAST_ID); + mBassClientService.resumeReceiversSourceSynchronization(); + assertThat(mStateMachines.size()).isEqualTo(2); + for (BassClientStateMachine sm : mStateMachines.values()) { + verify(sm, never()).sendMessage(any()); + } + } + + @Test + @EnableFlags({ + Flags.FLAG_LEAUDIO_BROADCAST_RESYNC_HELPER, + Flags.FLAG_LEAUDIO_BROADCAST_EXTRACT_PERIODIC_SCANNER_FROM_STATE_MACHINE + }) + public void multipleSinkMetadata_clearWhenAllDisconnected_duringSuspend() { + prepareConnectedDeviceGroup(); + startSearchingForSources(); + onScanResult(mSourceDevice, TEST_BROADCAST_ID); + onSyncEstablished(mSourceDevice, TEST_SYNC_HANDLE); + BluetoothLeBroadcastMetadata meta = createBroadcastMetadata(TEST_BROADCAST_ID); + verifyAddSourceForGroup(meta); + for (BassClientStateMachine sm : mStateMachines.values()) { + clearInvocations(sm); + } + prepareRemoteSourceState(meta, false, false); + + /* Unicast would like to stream */ + mBassClientService.handleUnicastSourceStreamStatusChange( + 3 /* STATUS_LOCAL_STREAM_REQUESTED_NO_CONTEXT_VALIDATE */); + verifyRemoveMessageAndInjectSourceRemoval(); + for (BassClientStateMachine sm : mStateMachines.values()) { + clearInvocations(sm); + } + + // Disconnect first sink not cause removing metadata + doReturn(BluetoothProfile.STATE_DISCONNECTED) + .when(mStateMachines.get(mCurrentDevice)) + .getConnectionState(); + doReturn(false).when(mStateMachines.get(mCurrentDevice)).isConnected(); + mBassClientService.connectionStateChanged( + mCurrentDevice, + BluetoothProfile.STATE_CONNECTED, + BluetoothProfile.STATE_DISCONNECTED); + injectRemoteSourceStateRemoval(mStateMachines.get(mCurrentDevice), TEST_SOURCE_ID); + + // Connect again first sink + doReturn(BluetoothProfile.STATE_CONNECTED) + .when(mStateMachines.get(mCurrentDevice)) + .getConnectionState(); + doReturn(true).when(mStateMachines.get(mCurrentDevice)).isConnected(); + prepareRemoteSourceState(meta, false, false); + + // Cache and resume should resume all devices + mBassClientService.cacheSuspendingSources(TEST_BROADCAST_ID); + mBassClientService.resumeReceiversSourceSynchronization(); + verifyAllGroupMembersGettingUpdateOrAddSource(meta); + for (BassClientStateMachine sm : mStateMachines.values()) { + clearInvocations(sm); + } + + /* Unicast would like to stream */ + mBassClientService.handleUnicastSourceStreamStatusChange( + 3 /* STATUS_LOCAL_STREAM_REQUESTED_NO_CONTEXT_VALIDATE */); + verifyRemoveMessageAndInjectSourceRemoval(); + for (BassClientStateMachine sm : mStateMachines.values()) { + clearInvocations(sm); + } + + // Disconnect first sink not cause removing metadata + doReturn(BluetoothProfile.STATE_DISCONNECTED) + .when(mStateMachines.get(mCurrentDevice)) + .getConnectionState(); + doReturn(false).when(mStateMachines.get(mCurrentDevice)).isConnected(); + mBassClientService.connectionStateChanged( + mCurrentDevice, + BluetoothProfile.STATE_CONNECTED, + BluetoothProfile.STATE_DISCONNECTED); + injectRemoteSourceStateRemoval(mStateMachines.get(mCurrentDevice), TEST_SOURCE_ID); + + // Disconnect second sink cause remove metada for both devices + doReturn(BluetoothProfile.STATE_DISCONNECTED) + .when(mStateMachines.get(mCurrentDevice1)) + .getConnectionState(); + doReturn(false).when(mStateMachines.get(mCurrentDevice1)).isConnected(); + mBassClientService.connectionStateChanged( + mCurrentDevice1, + BluetoothProfile.STATE_CONNECTED, + BluetoothProfile.STATE_DISCONNECTED); + injectRemoteSourceStateRemoval(mStateMachines.get(mCurrentDevice1), TEST_SOURCE_ID + 1); + + // Connect again both devices + doReturn(BluetoothProfile.STATE_CONNECTED) + .when(mStateMachines.get(mCurrentDevice)) + .getConnectionState(); + doReturn(true).when(mStateMachines.get(mCurrentDevice)).isConnected(); + doReturn(BluetoothProfile.STATE_CONNECTED) + .when(mStateMachines.get(mCurrentDevice1)) + .getConnectionState(); + doReturn(true).when(mStateMachines.get(mCurrentDevice1)).isConnected(); + prepareRemoteSourceState(meta, false, false); + + // Cache and resume should not resume at all + mBassClientService.cacheSuspendingSources(TEST_BROADCAST_ID); + mBassClientService.resumeReceiversSourceSynchronization(); + assertThat(mStateMachines.size()).isEqualTo(2); + for (BassClientStateMachine sm : mStateMachines.values()) { + verify(sm, never()).sendMessage(any()); + } + } + + @Test + @EnableFlags({ + Flags.FLAG_LEAUDIO_BROADCAST_RESYNC_HELPER, + Flags.FLAG_LEAUDIO_BROADCAST_EXTRACT_PERIODIC_SCANNER_FROM_STATE_MACHINE + }) + public void multipleSinkMetadata_clearWhenRemove_oneDisconnectedFirst() { + prepareConnectedDeviceGroup(); + startSearchingForSources(); + onScanResult(mSourceDevice, TEST_BROADCAST_ID); + onSyncEstablished(mSourceDevice, TEST_SYNC_HANDLE); + BluetoothLeBroadcastMetadata meta = createBroadcastMetadata(TEST_BROADCAST_ID); + mBassClientService.addSource(mCurrentDevice, meta, false); + mBassClientService.addSource(mCurrentDevice1, meta, false); + for (BassClientStateMachine sm : mStateMachines.values()) { + clearInvocations(sm); + } + prepareRemoteSourceState(meta, false, false); + + // Disconnect first sink not cause removing metadata + doReturn(BluetoothProfile.STATE_DISCONNECTED) + .when(mStateMachines.get(mCurrentDevice)) + .getConnectionState(); + doReturn(false).when(mStateMachines.get(mCurrentDevice)).isConnected(); + mBassClientService.connectionStateChanged( + mCurrentDevice, + BluetoothProfile.STATE_CONNECTED, + BluetoothProfile.STATE_DISCONNECTED); + injectRemoteSourceStateRemoval(mStateMachines.get(mCurrentDevice), TEST_SOURCE_ID); + + // Remove second source should remove metadata for both + // Do not clear receive state + mBassClientService.removeSource(mCurrentDevice1, TEST_SOURCE_ID + 1); + for (BassClientStateMachine sm : mStateMachines.values()) { + clearInvocations(sm); + } + + // Connect again first sink + doReturn(BluetoothProfile.STATE_CONNECTED) + .when(mStateMachines.get(mCurrentDevice)) + .getConnectionState(); + doReturn(true).when(mStateMachines.get(mCurrentDevice)).isConnected(); + prepareRemoteSourceState(meta, false, false); + + // Cache and resume should not resume at all + mBassClientService.cacheSuspendingSources(TEST_BROADCAST_ID); + mBassClientService.resumeReceiversSourceSynchronization(); + assertThat(mStateMachines.size()).isEqualTo(2); + for (BassClientStateMachine sm : mStateMachines.values()) { + verify(sm, never()).sendMessage(any()); + } + } + + @Test + @EnableFlags({ + Flags.FLAG_LEAUDIO_BROADCAST_RESYNC_HELPER, + Flags.FLAG_LEAUDIO_BROADCAST_EXTRACT_PERIODIC_SCANNER_FROM_STATE_MACHINE + }) + public void multipleSinkMetadata_clearWhenRemove_oneDisconnectedFirst_duringSuspend() { + prepareConnectedDeviceGroup(); + startSearchingForSources(); + onScanResult(mSourceDevice, TEST_BROADCAST_ID); + onSyncEstablished(mSourceDevice, TEST_SYNC_HANDLE); + BluetoothLeBroadcastMetadata meta = createBroadcastMetadata(TEST_BROADCAST_ID); + mBassClientService.addSource(mCurrentDevice, meta, false); + mBassClientService.addSource(mCurrentDevice1, meta, false); + for (BassClientStateMachine sm : mStateMachines.values()) { + clearInvocations(sm); + } + prepareRemoteSourceState(meta, false, false); + + /* Unicast would like to stream */ + mBassClientService.handleUnicastSourceStreamStatusChange( + 3 /* STATUS_LOCAL_STREAM_REQUESTED_NO_CONTEXT_VALIDATE */); + verifyRemoveMessageAndInjectSourceRemoval(); + for (BassClientStateMachine sm : mStateMachines.values()) { + clearInvocations(sm); + } + + // Disconnect first sink not cause removing metadata + doReturn(BluetoothProfile.STATE_DISCONNECTED) + .when(mStateMachines.get(mCurrentDevice)) + .getConnectionState(); + doReturn(false).when(mStateMachines.get(mCurrentDevice)).isConnected(); + mBassClientService.connectionStateChanged( + mCurrentDevice, + BluetoothProfile.STATE_CONNECTED, + BluetoothProfile.STATE_DISCONNECTED); + injectRemoteSourceStateRemoval(mStateMachines.get(mCurrentDevice), TEST_SOURCE_ID); + + // Remove second source should remove metadata for both + // Do not clear receive state + mBassClientService.removeSource(mCurrentDevice1, TEST_SOURCE_ID + 1); + for (BassClientStateMachine sm : mStateMachines.values()) { + clearInvocations(sm); + } + + // Connect again first sink + doReturn(BluetoothProfile.STATE_CONNECTED) + .when(mStateMachines.get(mCurrentDevice)) + .getConnectionState(); + doReturn(true).when(mStateMachines.get(mCurrentDevice)).isConnected(); + prepareRemoteSourceState(meta, false, false); + + // Cache and resume should not resume at all + mBassClientService.cacheSuspendingSources(TEST_BROADCAST_ID); + mBassClientService.resumeReceiversSourceSynchronization(); + assertThat(mStateMachines.size()).isEqualTo(2); + for (BassClientStateMachine sm : mStateMachines.values()) { + verify(sm, never()).sendMessage(any()); + } + } + + @Test + @EnableFlags({ + Flags.FLAG_LEAUDIO_BROADCAST_RESYNC_HELPER, + Flags.FLAG_LEAUDIO_BROADCAST_EXTRACT_PERIODIC_SCANNER_FROM_STATE_MACHINE + }) + public void clearPendingSourceToAdd_oneByOne_whenDisconnected() { + prepareConnectedDeviceGroup(); + startSearchingForSources(); + onScanResult(mSourceDevice, TEST_BROADCAST_ID); + onSyncEstablished(mSourceDevice, TEST_SYNC_HANDLE); + + // Sync lost without triggering timeout to keep cache + onSyncLost(); + + // Add source force syncing to broadcaster and add sinks to pendingSourcesToAdd + BluetoothLeBroadcastMetadata meta = createBroadcastMetadata(TEST_BROADCAST_ID); + mBassClientService.addSource(mCurrentDevice, meta, false); + mBassClientService.addSource(mCurrentDevice1, meta, false); + + // Disconnect first sink should remove pendingSourceToAdd for it + doReturn(BluetoothProfile.STATE_DISCONNECTED) + .when(mStateMachines.get(mCurrentDevice)) + .getConnectionState(); + doReturn(false).when(mStateMachines.get(mCurrentDevice)).isConnected(); + mBassClientService.connectionStateChanged( + mCurrentDevice, + BluetoothProfile.STATE_CONNECTED, + BluetoothProfile.STATE_DISCONNECTED); + injectRemoteSourceStateRemoval(mStateMachines.get(mCurrentDevice), TEST_SOURCE_ID); + + // Sync established should add source on only one sink + onSyncEstablished(mSourceDevice, TEST_SYNC_HANDLE); + assertThat(mStateMachines.size()).isEqualTo(2); + for (BassClientStateMachine sm : mStateMachines.values()) { + if (sm.getDevice().equals(mCurrentDevice)) { + verify(sm, never()).sendMessage(any()); + } else if (sm.getDevice().equals(mCurrentDevice1)) { + ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class); + verify(sm, atLeast(1)).sendMessage(messageCaptor.capture()); + + Message msg = + messageCaptor.getAllValues().stream() + .filter(m -> (m.what == BassClientStateMachine.ADD_BCAST_SOURCE)) + .findFirst() + .orElse(null); + assertThat(msg).isNotNull(); + clearInvocations(sm); + } else { + throw new AssertionError("Unexpected device"); + } + } + } + + @Test + @EnableFlags({ + Flags.FLAG_LEAUDIO_BROADCAST_RESYNC_HELPER, + Flags.FLAG_LEAUDIO_BROADCAST_EXTRACT_PERIODIC_SCANNER_FROM_STATE_MACHINE + }) + public void clearPendingSourceToAdd_group_whenDisconnected() { + prepareConnectedDeviceGroup(); + startSearchingForSources(); + onScanResult(mSourceDevice, TEST_BROADCAST_ID); + onSyncEstablished(mSourceDevice, TEST_SYNC_HANDLE); + + // Sync lost without triggering timeout to keep cache + onSyncLost(); + + // Add source force syncing to broadcaster and add sinks to pendingSourcesToAdd + BluetoothLeBroadcastMetadata meta = createBroadcastMetadata(TEST_BROADCAST_ID); + mBassClientService.addSource(mCurrentDevice, meta, true); + + // Disconnect first sink should remove pendingSourceToAdd for it + doReturn(BluetoothProfile.STATE_DISCONNECTED) + .when(mStateMachines.get(mCurrentDevice)) + .getConnectionState(); + doReturn(false).when(mStateMachines.get(mCurrentDevice)).isConnected(); + mBassClientService.connectionStateChanged( + mCurrentDevice, + BluetoothProfile.STATE_CONNECTED, + BluetoothProfile.STATE_DISCONNECTED); + injectRemoteSourceStateRemoval(mStateMachines.get(mCurrentDevice), TEST_SOURCE_ID); + + // Sync established should add source on only one sink + onSyncEstablished(mSourceDevice, TEST_SYNC_HANDLE); + assertThat(mStateMachines.size()).isEqualTo(2); + for (BassClientStateMachine sm : mStateMachines.values()) { + if (sm.getDevice().equals(mCurrentDevice)) { + verify(sm, never()).sendMessage(any()); + } else if (sm.getDevice().equals(mCurrentDevice1)) { + ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class); + verify(sm, atLeast(1)).sendMessage(messageCaptor.capture()); + + Message msg = + messageCaptor.getAllValues().stream() + .filter(m -> (m.what == BassClientStateMachine.ADD_BCAST_SOURCE)) + .findFirst() + .orElse(null); + assertThat(msg).isNotNull(); + clearInvocations(sm); + } else { + throw new AssertionError("Unexpected device"); + } + } + } + private void verifyConnectionStateIntent(BluetoothDevice device, int newState, int prevState) { verifyIntentSent( hasAction(BluetoothLeBroadcastAssistant.ACTION_CONNECTION_STATE_CHANGED), diff --git a/android/app/tests/unit/src/com/android/bluetooth/bass_client/BassClientStateMachineTest.java b/android/app/tests/unit/src/com/android/bluetooth/bass_client/BassClientStateMachineTest.java index 4241c0af43..6578fa6a45 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/bass_client/BassClientStateMachineTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/bass_client/BassClientStateMachineTest.java @@ -24,6 +24,7 @@ import static androidx.test.espresso.intent.matcher.IntentMatchers.hasAction; import static androidx.test.espresso.intent.matcher.IntentMatchers.hasExtra; import static androidx.test.espresso.intent.matcher.IntentMatchers.hasFlag; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.android.bluetooth.bass_client.BassClientStateMachine.ADD_BCAST_SOURCE; import static com.android.bluetooth.bass_client.BassClientStateMachine.CANCEL_PENDING_SOURCE_OPERATION; @@ -123,8 +124,6 @@ import org.mockito.InOrder; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.hamcrest.MockitoHamcrest; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.util.ArrayList; import java.util.Arrays; @@ -135,7 +134,7 @@ import java.util.UUID; @MediumTest @RunWith(JUnit4.class) public class BassClientStateMachineTest { - @Rule public final MockitoRule mockito = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); diff --git a/android/app/tests/unit/src/com/android/bluetooth/bass_client/BleBroadcastAssistantBinderTest.java b/android/app/tests/unit/src/com/android/bluetooth/bass_client/BleBroadcastAssistantBinderTest.java index cfeac8a4ff..aa3a14ff1e 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/bass_client/BleBroadcastAssistantBinderTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/bass_client/BleBroadcastAssistantBinderTest.java @@ -18,6 +18,7 @@ package com.android.bluetooth.bass_client; import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTED; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.google.common.truth.Truth.assertThat; @@ -43,8 +44,6 @@ import org.junit.runner.RunWith; import org.junit.runners.JUnit4; import org.mockito.Mock; import org.mockito.Mockito; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.util.Collections; import java.util.List; @@ -52,7 +51,7 @@ import java.util.List; @RunWith(JUnit4.class) public class BleBroadcastAssistantBinderTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); private final BluetoothAdapter mAdapter = InstrumentationRegistry.getInstrumentation() diff --git a/android/app/tests/unit/src/com/android/bluetooth/btservice/ActiveDeviceManagerTest.java b/android/app/tests/unit/src/com/android/bluetooth/btservice/ActiveDeviceManagerTest.java index 4240e5de25..ec629ddf46 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/btservice/ActiveDeviceManagerTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/btservice/ActiveDeviceManagerTest.java @@ -16,7 +16,9 @@ package com.android.bluetooth.btservice; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; +import static com.android.bluetooth.TestUtils.mockGetSystemService; import static com.google.common.truth.Truth.assertThat; @@ -71,8 +73,6 @@ import org.mockito.InOrder; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.Spy; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.util.ArrayList; import java.util.List; @@ -103,7 +103,7 @@ public class ActiveDeviceManagerTest { private TestLooper mTestLooper; @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private AdapterService mAdapterService; @Mock private ServiceFactory mServiceFactory; @@ -124,9 +124,8 @@ public class ActiveDeviceManagerTest { mDatabaseManager = new TestDatabaseManager(mAdapterService); - when(mAdapterService.getSystemService(Context.AUDIO_SERVICE)).thenReturn(mAudioManager); - when(mAdapterService.getSystemServiceName(AudioManager.class)) - .thenReturn(Context.AUDIO_SERVICE); + mockGetSystemService( + mAdapterService, Context.AUDIO_SERVICE, AudioManager.class, mAudioManager); when(mAdapterService.getDatabase()).thenReturn(mDatabaseManager); when(mServiceFactory.getA2dpService()).thenReturn(mA2dpService); when(mServiceFactory.getHeadsetService()).thenReturn(mHeadsetService); diff --git a/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterPropertiesTest.java b/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterPropertiesTest.java index 2bc29ec34c..93f3f5f824 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterPropertiesTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterPropertiesTest.java @@ -15,6 +15,9 @@ */ package com.android.bluetooth.btservice; +import static com.android.bluetooth.TestUtils.MockitoRule; +import static com.android.bluetooth.TestUtils.mockGetSystemService; + import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.any; @@ -40,8 +43,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; @MediumTest @RunWith(AndroidJUnit4.class) @@ -49,30 +50,31 @@ public class AdapterPropertiesTest { private static final byte[] TEST_BT_ADDR_BYTES = {00, 11, 22, 33, 44, 55}; private static final byte[] TEST_BT_ADDR_BYTES_2 = {00, 11, 22, 33, 44, 66}; - private BluetoothManager mBluetoothManager; + private final Context mTargetContext = + InstrumentationRegistry.getInstrumentation().getTargetContext(); + private final BluetoothManager mBluetoothManager = + mTargetContext.getSystemService(BluetoothManager.class); + private AdapterProperties mAdapterProperties; private RemoteDevices mRemoteDevices; private HandlerThread mHandlerThread; - private Context mTargetContext; - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private AdapterService mAdapterService; @Mock private AdapterNativeInterface mNativeInterface; @Before public void setUp() throws Exception { - mTargetContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); - doReturn(mNativeInterface).when(mAdapterService).getNative(); mHandlerThread = new HandlerThread("RemoteDevicesTestHandlerThread"); mHandlerThread.start(); - mBluetoothManager = mTargetContext.getSystemService(BluetoothManager.class); - when(mAdapterService.getSystemService(Context.BLUETOOTH_SERVICE)) - .thenReturn(mBluetoothManager); - when(mAdapterService.getSystemServiceName(BluetoothManager.class)) - .thenReturn(Context.BLUETOOTH_SERVICE); + mockGetSystemService( + mAdapterService, + Context.BLUETOOTH_SERVICE, + BluetoothManager.class, + mBluetoothManager); when(mAdapterService.getIdentityAddress(Utils.getAddressStringFromByte(TEST_BT_ADDR_BYTES))) .thenReturn(Utils.getAddressStringFromByte(TEST_BT_ADDR_BYTES)); diff --git a/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceBinderTest.java b/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceBinderTest.java index eefa37fd3a..8c666babfd 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceBinderTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceBinderTest.java @@ -16,6 +16,8 @@ package com.android.bluetooth.btservice; +import static com.android.bluetooth.TestUtils.MockitoRule; + import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; @@ -32,13 +34,11 @@ import org.junit.Rule; import org.junit.Test; import org.mockito.Mock; import org.mockito.Mockito; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.io.FileDescriptor; public class AdapterServiceBinderTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private AdapterService mService; @Mock private AdapterProperties mAdapterProperties; diff --git a/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceTest.java index 756e199add..854317fb06 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceTest.java @@ -24,6 +24,7 @@ import static android.bluetooth.BluetoothAdapter.STATE_ON; import static android.bluetooth.BluetoothAdapter.STATE_TURNING_OFF; import static android.bluetooth.BluetoothAdapter.STATE_TURNING_ON; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.google.common.truth.Truth.assertThat; @@ -95,8 +96,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InOrder; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import platform.test.runner.parameterized.ParameterizedAndroidJunit4; import platform.test.runner.parameterized.Parameters; @@ -141,7 +140,7 @@ public class AdapterServiceTest { } } - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); private @Mock Context mMockContext; private @Mock ApplicationInfo mMockApplicationInfo; diff --git a/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterSuspendTest.java b/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterSuspendTest.java index 2cca8892d7..c175cfaa02 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterSuspendTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterSuspendTest.java @@ -18,6 +18,8 @@ package com.android.bluetooth.btservice; import static android.bluetooth.BluetoothAdapter.SCAN_MODE_CONNECTABLE; import static android.bluetooth.BluetoothAdapter.SCAN_MODE_NONE; +import static com.android.bluetooth.TestUtils.MockitoRule; + import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.anyLong; @@ -38,8 +40,6 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; @SmallTest @RunWith(AndroidJUnit4.class) @@ -48,7 +48,7 @@ public class AdapterSuspendTest { private DeviceStateManager mDeviceStateManager; private AdapterSuspend mAdapterSuspend; - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private AdapterNativeInterface mAdapterNativeInterface; @Before diff --git a/android/app/tests/unit/src/com/android/bluetooth/btservice/BondStateMachineTest.java b/android/app/tests/unit/src/com/android/bluetooth/btservice/BondStateMachineTest.java index 7a47478fdd..044ededd4a 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/btservice/BondStateMachineTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/btservice/BondStateMachineTest.java @@ -17,6 +17,9 @@ package com.android.bluetooth.btservice; import static android.Manifest.permission.BLUETOOTH_CONNECT; +import static com.android.bluetooth.TestUtils.MockitoRule; +import static com.android.bluetooth.TestUtils.mockGetSystemService; + import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.*; @@ -45,8 +48,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; @MediumTest @RunWith(AndroidJUnit4.class) @@ -67,34 +68,36 @@ public class BondStateMachineTest { private static final int BOND_BONDING = BluetoothDevice.BOND_BONDING; private static final int BOND_BONDED = BluetoothDevice.BOND_BONDED; - private BluetoothManager mBluetoothManager; + private final Context mTargetContext = + InstrumentationRegistry.getInstrumentation().getTargetContext(); + private final BluetoothManager mBluetoothManager = + mTargetContext.getSystemService(BluetoothManager.class); + private AdapterProperties mAdapterProperties; private BluetoothDevice mDevice; - private Context mTargetContext; private RemoteDevices mRemoteDevices; private BondStateMachine mBondStateMachine; private HandlerThread mHandlerThread; private RemoteDevices.DeviceProperties mDeviceProperties; private int mVerifyCount = 0; - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private AdapterService mAdapterService; @Mock private AdapterNativeInterface mNativeInterface; @Before public void setUp() throws Exception { - mTargetContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); TestUtils.setAdapterService(mAdapterService); doReturn(mNativeInterface).when(mAdapterService).getNative(); mHandlerThread = new HandlerThread("BondStateMachineTestHandlerThread"); mHandlerThread.start(); - mBluetoothManager = mTargetContext.getSystemService(BluetoothManager.class); - when(mAdapterService.getSystemService(Context.BLUETOOTH_SERVICE)) - .thenReturn(mBluetoothManager); - when(mAdapterService.getSystemServiceName(BluetoothManager.class)) - .thenReturn(Context.BLUETOOTH_SERVICE); + mockGetSystemService( + mAdapterService, + Context.BLUETOOTH_SERVICE, + BluetoothManager.class, + mBluetoothManager); mRemoteDevices = new RemoteDevices(mAdapterService, mHandlerThread.getLooper()); mRemoteDevices.reset(); diff --git a/android/app/tests/unit/src/com/android/bluetooth/btservice/CompanionManagerTest.java b/android/app/tests/unit/src/com/android/bluetooth/btservice/CompanionManagerTest.java index 3f1e4f0627..2b3d692035 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/btservice/CompanionManagerTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/btservice/CompanionManagerTest.java @@ -15,6 +15,8 @@ */ package com.android.bluetooth.btservice; +import static com.android.bluetooth.TestUtils.MockitoRule; + import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.*; @@ -37,8 +39,6 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; @MediumTest @RunWith(AndroidJUnit4.class) @@ -51,7 +51,7 @@ public class CompanionManagerTest { private HandlerThread mHandlerThread; - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private AdapterService mAdapterService; @Mock SharedPreferences mSharedPreferences; diff --git a/android/app/tests/unit/src/com/android/bluetooth/btservice/DataMigrationTest.java b/android/app/tests/unit/src/com/android/bluetooth/btservice/DataMigrationTest.java index dc840b536b..b7d10c518b 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/btservice/DataMigrationTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/btservice/DataMigrationTest.java @@ -20,6 +20,8 @@ import static android.bluetooth.BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED; import static android.bluetooth.BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED; import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_FORBIDDEN; +import static com.android.bluetooth.TestUtils.MockitoRule; + import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; @@ -54,8 +56,6 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.util.ArrayList; import java.util.Arrays; @@ -75,7 +75,7 @@ public class DataMigrationTest { private Context mTargetContext; private SharedPreferences mPrefs; - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private Context mMockContext; diff --git a/android/app/tests/unit/src/com/android/bluetooth/btservice/MetricsLoggerTest.java b/android/app/tests/unit/src/com/android/bluetooth/btservice/MetricsLoggerTest.java index 9e4a6347f9..27ca9a3ceb 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/btservice/MetricsLoggerTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/btservice/MetricsLoggerTest.java @@ -15,6 +15,7 @@ */ package com.android.bluetooth.btservice; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.google.common.truth.Truth.assertThat; @@ -39,8 +40,6 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.io.ByteArrayInputStream; import java.io.IOException; @@ -83,7 +82,7 @@ public class MetricsLoggerTest { } private TestableMetricsLogger mTestableMetricsLogger; - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private AdapterService mAdapterService; @Mock private RemoteDevices mRemoteDevices; diff --git a/android/app/tests/unit/src/com/android/bluetooth/btservice/PhonePolicyTest.java b/android/app/tests/unit/src/com/android/bluetooth/btservice/PhonePolicyTest.java index c419bdba52..046bd4b75e 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/btservice/PhonePolicyTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/btservice/PhonePolicyTest.java @@ -24,6 +24,7 @@ import static android.bluetooth.BluetoothProfile.STATE_CONNECTING; import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTED; import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTING; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static org.mockito.Mockito.any; @@ -74,8 +75,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InOrder; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.util.ArrayList; import java.util.Collections; @@ -84,7 +83,7 @@ import java.util.List; @MediumTest @RunWith(AndroidJUnit4.class) public class PhonePolicyTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); @Mock private AdapterService mAdapterService; diff --git a/android/app/tests/unit/src/com/android/bluetooth/btservice/ProfileServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/btservice/ProfileServiceTest.java index 95f7faf5f6..6c5586a6d0 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/btservice/ProfileServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/btservice/ProfileServiceTest.java @@ -16,6 +16,8 @@ package com.android.bluetooth.btservice; +import static com.android.bluetooth.TestUtils.MockitoRule; + import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; @@ -52,8 +54,6 @@ import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.Spy; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.lang.reflect.InvocationTargetException; import java.util.Arrays; @@ -71,7 +71,7 @@ public class ProfileServiceTest { private AdapterService mAdapterService = new AdapterService(InstrumentationRegistry.getInstrumentation().getTargetContext()); - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private DatabaseManager mDatabaseManager; @Mock private TelephonyManager mMockTelephonyManager; diff --git a/android/app/tests/unit/src/com/android/bluetooth/btservice/RemoteDevicesTest.java b/android/app/tests/unit/src/com/android/bluetooth/btservice/RemoteDevicesTest.java index 3ca2ca25f6..c94ae6ab2b 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/btservice/RemoteDevicesTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/btservice/RemoteDevicesTest.java @@ -2,7 +2,9 @@ package com.android.bluetooth.btservice; import static android.Manifest.permission.BLUETOOTH_CONNECT; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; +import static com.android.bluetooth.TestUtils.mockGetSystemService; import static com.google.common.truth.Truth.assertThat; @@ -42,8 +44,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.util.ArrayList; @@ -51,7 +51,7 @@ import java.util.ArrayList; @RunWith(AndroidJUnit4.class) public class RemoteDevicesTest { @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private AdapterService mAdapterService; @@ -75,10 +75,11 @@ public class RemoteDevicesTest { InstrumentationRegistry.getInstrumentation() .acquireLooperManager(mHandlerThread.getLooper()); - when(mAdapterService.getSystemService(Context.BLUETOOTH_SERVICE)) - .thenReturn(mBluetoothManager); - when(mAdapterService.getSystemServiceName(BluetoothManager.class)) - .thenReturn(Context.BLUETOOTH_SERVICE); + mockGetSystemService( + mAdapterService, + Context.BLUETOOTH_SERVICE, + BluetoothManager.class, + mBluetoothManager); mRemoteDevices = new RemoteDevices(mAdapterService, mHandlerThread.getLooper()); verify(mAdapterService).getSystemService(Context.BLUETOOTH_SERVICE); diff --git a/android/app/tests/unit/src/com/android/bluetooth/btservice/SilenceDeviceManagerTest.java b/android/app/tests/unit/src/com/android/bluetooth/btservice/SilenceDeviceManagerTest.java index c851e9bbf6..1e666f7dd4 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/btservice/SilenceDeviceManagerTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/btservice/SilenceDeviceManagerTest.java @@ -18,6 +18,7 @@ package com.android.bluetooth.btservice; import static android.Manifest.permission.BLUETOOTH_CONNECT; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.google.common.truth.Truth.assertThat; @@ -46,13 +47,11 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; @MediumTest @RunWith(AndroidJUnit4.class) public class SilenceDeviceManagerTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private AdapterService mAdapterService; @Mock private ServiceFactory mServiceFactory; diff --git a/android/app/tests/unit/src/com/android/bluetooth/btservice/bluetoothKeystore/BluetoothKeystoreServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/btservice/bluetoothKeystore/BluetoothKeystoreServiceTest.java index 93ce02664c..9ddb69c4f1 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/btservice/bluetoothKeystore/BluetoothKeystoreServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/btservice/bluetoothKeystore/BluetoothKeystoreServiceTest.java @@ -16,6 +16,8 @@ package com.android.bluetooth.btservice.bluetoothkeystore; +import static com.android.bluetooth.TestUtils.MockitoRule; + import static com.google.common.truth.Truth.assertThat; import android.os.Binder; @@ -30,8 +32,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.io.IOException; import java.nio.file.Files; @@ -47,7 +47,7 @@ public final class BluetoothKeystoreServiceTest { private static final String TAG = "BluetoothKeystoreServiceTest"; private BluetoothKeystoreService mBluetoothKeystoreService; - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private BluetoothKeystoreNativeInterface mMockNativeInterface; diff --git a/android/app/tests/unit/src/com/android/bluetooth/btservice/storage/DatabaseManagerTest.java b/android/app/tests/unit/src/com/android/bluetooth/btservice/storage/DatabaseManagerTest.java index ab6b46f672..c06dbb5d08 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/btservice/storage/DatabaseManagerTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/btservice/storage/DatabaseManagerTest.java @@ -16,6 +16,7 @@ package com.android.bluetooth.btservice.storage; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.google.common.truth.Truth.assertThat; @@ -60,8 +61,6 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import org.mockito.stubbing.Answer; import java.io.IOException; @@ -73,7 +72,7 @@ import java.util.concurrent.TimeUnit; @MediumTest @RunWith(AndroidJUnit4.class) public final class DatabaseManagerTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private AdapterService mAdapterService; diff --git a/android/app/tests/unit/src/com/android/bluetooth/csip/BluetoothCsisBinderTest.java b/android/app/tests/unit/src/com/android/bluetooth/csip/BluetoothCsisBinderTest.java index a6852696c3..6ea19c5477 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/csip/BluetoothCsisBinderTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/csip/BluetoothCsisBinderTest.java @@ -16,6 +16,7 @@ package com.android.bluetooth.csip; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static org.mockito.Mockito.mock; @@ -31,11 +32,9 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; public class BluetoothCsisBinderTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private CsipSetCoordinatorService mService; diff --git a/android/app/tests/unit/src/com/android/bluetooth/csip/CsipSetCoordinatorServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/csip/CsipSetCoordinatorServiceTest.java index b1497609de..1e863efd96 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/csip/CsipSetCoordinatorServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/csip/CsipSetCoordinatorServiceTest.java @@ -33,6 +33,7 @@ import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTED; import static androidx.test.espresso.intent.matcher.IntentMatchers.hasAction; import static androidx.test.espresso.intent.matcher.IntentMatchers.hasExtra; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.google.common.truth.Truth.assertThat; @@ -77,8 +78,6 @@ import org.mockito.InOrder; import org.mockito.Mock; import org.mockito.Spy; import org.mockito.hamcrest.MockitoHamcrest; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.util.List; import java.util.UUID; @@ -86,7 +85,7 @@ import java.util.UUID; @MediumTest @RunWith(AndroidJUnit4.class) public class CsipSetCoordinatorServiceTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Spy private ServiceFactory mServiceFactory = new ServiceFactory(); @Mock private AdapterService mAdapterService; diff --git a/android/app/tests/unit/src/com/android/bluetooth/csip/CsipSetCoordinatorStateMachineTest.java b/android/app/tests/unit/src/com/android/bluetooth/csip/CsipSetCoordinatorStateMachineTest.java index 576e544413..48eb568b8c 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/csip/CsipSetCoordinatorStateMachineTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/csip/CsipSetCoordinatorStateMachineTest.java @@ -22,6 +22,7 @@ import static android.bluetooth.BluetoothProfile.STATE_CONNECTING; import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTED; import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTING; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.google.common.truth.Truth.assertThat; @@ -50,8 +51,6 @@ import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.Mockito; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; @MediumTest @RunWith(AndroidJUnit4.class) @@ -63,7 +62,7 @@ public class CsipSetCoordinatorStateMachineTest { private CsipSetCoordinatorStateMachineWrapper mStateMachine; private static final int TIMEOUT_MS = 1000; - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private AdapterService mAdapterService; @Mock private CsipSetCoordinatorService mService; diff --git a/android/app/tests/unit/src/com/android/bluetooth/gatt/AdvertiseBinderTest.java b/android/app/tests/unit/src/com/android/bluetooth/gatt/AdvertiseBinderTest.java index 097c4ca4b8..f90223cd24 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/gatt/AdvertiseBinderTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/gatt/AdvertiseBinderTest.java @@ -16,6 +16,8 @@ package com.android.bluetooth.gatt; +import static com.android.bluetooth.TestUtils.MockitoRule; + import static org.mockito.Mockito.any; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; @@ -39,14 +41,12 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; /** Test cases for {@link AdvertiseBinder}. */ @SmallTest @RunWith(AndroidJUnit4.class) public class AdvertiseBinderTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private AdapterService mAdapterService; @Mock private AdvertiseManager mAdvertiseManager; diff --git a/android/app/tests/unit/src/com/android/bluetooth/gatt/AdvertiseManagerTest.java b/android/app/tests/unit/src/com/android/bluetooth/gatt/AdvertiseManagerTest.java index 351b919c07..8537795af5 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/gatt/AdvertiseManagerTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/gatt/AdvertiseManagerTest.java @@ -16,6 +16,8 @@ package com.android.bluetooth.gatt; +import static com.android.bluetooth.TestUtils.MockitoRule; + import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doNothing; @@ -42,8 +44,6 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import platform.test.runner.parameterized.ParameterizedAndroidJunit4; import platform.test.runner.parameterized.Parameters; @@ -55,7 +55,7 @@ import java.util.List; @RunWith(ParameterizedAndroidJunit4.class) public class AdvertiseManagerTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Rule public final SetFlagsRule mSetFlagsRule; @Mock private AdapterService mAdapterService; diff --git a/android/app/tests/unit/src/com/android/bluetooth/gatt/AdvertiserMapTest.java b/android/app/tests/unit/src/com/android/bluetooth/gatt/AdvertiserMapTest.java index 2add1b91cb..df0d609e89 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/gatt/AdvertiserMapTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/gatt/AdvertiserMapTest.java @@ -16,6 +16,8 @@ package com.android.bluetooth.gatt; +import static com.android.bluetooth.TestUtils.MockitoRule; + import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.anyInt; @@ -43,8 +45,6 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; /** Test cases for {@link AdvertiserMap}. */ @SmallTest @@ -52,7 +52,7 @@ import org.mockito.junit.MockitoRule; public class AdvertiserMapTest { private static final String APP_NAME = "com.android.what.a.name"; - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private AdapterService mAdapterService; @Mock private PackageManager mMockPackageManager; diff --git a/android/app/tests/unit/src/com/android/bluetooth/gatt/AppAdvertiseStatsTest.java b/android/app/tests/unit/src/com/android/bluetooth/gatt/AppAdvertiseStatsTest.java index 3208f4c526..a9fc2b6e3f 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/gatt/AppAdvertiseStatsTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/gatt/AppAdvertiseStatsTest.java @@ -16,6 +16,8 @@ package com.android.bluetooth.gatt; +import static com.android.bluetooth.TestUtils.MockitoRule; + import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.eq; @@ -47,8 +49,6 @@ import org.mockito.ArgumentCaptor; import org.mockito.Captor; import org.mockito.Mock; import org.mockito.Mockito; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @@ -61,7 +61,7 @@ public class AppAdvertiseStatsTest { private CountDownLatch mLatch; - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); diff --git a/android/app/tests/unit/src/com/android/bluetooth/gatt/ContextMapTest.java b/android/app/tests/unit/src/com/android/bluetooth/gatt/ContextMapTest.java index e1ddf9616d..dac06a7086 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/gatt/ContextMapTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/gatt/ContextMapTest.java @@ -16,6 +16,8 @@ package com.android.bluetooth.gatt; +import static com.android.bluetooth.TestUtils.MockitoRule; + import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.anyInt; @@ -41,8 +43,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.Spy; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.util.List; import java.util.UUID; @@ -63,7 +63,7 @@ public class ContextMapTest { @Rule public final ServiceTestRule mServiceRule = new ServiceTestRule(); - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private AdapterService mAdapterService; @Mock private IBluetoothGattCallback mMockCallback; diff --git a/android/app/tests/unit/src/com/android/bluetooth/gatt/DistanceMeasurementBinderTest.java b/android/app/tests/unit/src/com/android/bluetooth/gatt/DistanceMeasurementBinderTest.java index da4b67adde..05aff3911c 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/gatt/DistanceMeasurementBinderTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/gatt/DistanceMeasurementBinderTest.java @@ -16,6 +16,7 @@ package com.android.bluetooth.gatt; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static org.mockito.Mockito.mock; @@ -41,8 +42,6 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.util.Collections; import java.util.UUID; @@ -51,7 +50,7 @@ import java.util.UUID; @SmallTest @RunWith(AndroidJUnit4.class) public class DistanceMeasurementBinderTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private DistanceMeasurementManager mDistanceMeasurementManager; @Mock private AdapterService mAdapterService; diff --git a/android/app/tests/unit/src/com/android/bluetooth/gatt/DistanceMeasurementManagerTest.java b/android/app/tests/unit/src/com/android/bluetooth/gatt/DistanceMeasurementManagerTest.java index c1eeb14e06..3fafb0678a 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/gatt/DistanceMeasurementManagerTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/gatt/DistanceMeasurementManagerTest.java @@ -16,6 +16,7 @@ package com.android.bluetooth.gatt; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.google.common.truth.Truth.assertThat; @@ -48,8 +49,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.util.UUID; @@ -57,7 +56,7 @@ import java.util.UUID; @SmallTest @RunWith(AndroidJUnit4.class) public class DistanceMeasurementManagerTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private DistanceMeasurementNativeInterface mDistanceMeasurementNativeInterface; @Mock private AdapterService mAdapterService; diff --git a/android/app/tests/unit/src/com/android/bluetooth/gatt/DistanceMeasurementTrackerTest.java b/android/app/tests/unit/src/com/android/bluetooth/gatt/DistanceMeasurementTrackerTest.java index e79e885d0e..8fee9a8e24 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/gatt/DistanceMeasurementTrackerTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/gatt/DistanceMeasurementTrackerTest.java @@ -16,6 +16,7 @@ package com.android.bluetooth.gatt; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.google.common.truth.Truth.assertThat; @@ -39,8 +40,6 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.util.UUID; @@ -48,7 +47,7 @@ import java.util.UUID; @SmallTest @RunWith(AndroidJUnit4.class) public class DistanceMeasurementTrackerTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private DistanceMeasurementManager mDistanceMeasurementManager; @Mock private IDistanceMeasurementCallback mCallback; diff --git a/android/app/tests/unit/src/com/android/bluetooth/gatt/GattDebugUtilsTest.java b/android/app/tests/unit/src/com/android/bluetooth/gatt/GattDebugUtilsTest.java index dbf2e5c167..4237759122 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/gatt/GattDebugUtilsTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/gatt/GattDebugUtilsTest.java @@ -16,6 +16,8 @@ package com.android.bluetooth.gatt; +import static com.android.bluetooth.TestUtils.MockitoRule; + import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.verify; @@ -29,15 +31,13 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; /** Test cases for {@link GattDebugUtils}. */ @SmallTest @RunWith(AndroidJUnit4.class) public class GattDebugUtilsTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private GattService mService; diff --git a/android/app/tests/unit/src/com/android/bluetooth/gatt/GattServiceBinderTest.java b/android/app/tests/unit/src/com/android/bluetooth/gatt/GattServiceBinderTest.java index 3d749abb73..f982200eb6 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/gatt/GattServiceBinderTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/gatt/GattServiceBinderTest.java @@ -16,6 +16,8 @@ package com.android.bluetooth.gatt; +import static com.android.bluetooth.TestUtils.MockitoRule; + import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -36,8 +38,6 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.util.UUID; @@ -47,7 +47,7 @@ public class GattServiceBinderTest { private static final String REMOTE_DEVICE_ADDRESS = "00:00:00:00:00:00"; - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private GattService mService; diff --git a/android/app/tests/unit/src/com/android/bluetooth/gatt/GattServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/gatt/GattServiceTest.java index 22a90461ba..8e3fa172c9 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/gatt/GattServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/gatt/GattServiceTest.java @@ -16,6 +16,7 @@ package com.android.bluetooth.gatt; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.google.common.truth.Truth.assertThat; @@ -63,8 +64,6 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.util.ArrayList; import java.util.HashMap; @@ -78,7 +77,7 @@ import java.util.UUID; @SmallTest @RunWith(AndroidJUnit4.class) public class GattServiceTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); @Mock private ContextMap<IBluetoothGattCallback> mClientMap; diff --git a/android/app/tests/unit/src/com/android/bluetooth/hap/HapClientBinderTest.java b/android/app/tests/unit/src/com/android/bluetooth/hap/HapClientBinderTest.java index 00f9f92289..a0a123dcd9 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hap/HapClientBinderTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hap/HapClientBinderTest.java @@ -16,6 +16,7 @@ package com.android.bluetooth.hap; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static org.junit.Assert.assertThrows; @@ -40,13 +41,11 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.Mockito; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; @MediumTest @RunWith(AndroidJUnit4.class) public class HapClientBinderTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private HapClientService mHapClientService; diff --git a/android/app/tests/unit/src/com/android/bluetooth/hap/HapClientNativeCallbackTest.java b/android/app/tests/unit/src/com/android/bluetooth/hap/HapClientNativeCallbackTest.java index af1c3930da..85ba8fdb4e 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hap/HapClientNativeCallbackTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hap/HapClientNativeCallbackTest.java @@ -16,6 +16,8 @@ package com.android.bluetooth.hap; +import static com.android.bluetooth.TestUtils.MockitoRule; + import static org.mockito.Mockito.verify; import android.bluetooth.BluetoothHapPresetInfo; @@ -31,11 +33,9 @@ import org.junit.Test; import org.mockito.ArgumentCaptor; import org.mockito.Captor; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; public class HapClientNativeCallbackTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Rule public Expect expect = Expect.create(); @Mock private AdapterService mAdapterService; diff --git a/android/app/tests/unit/src/com/android/bluetooth/hap/HapClientServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/hap/HapClientServiceTest.java index 6e0b4b72e9..8693cca5a7 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hap/HapClientServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hap/HapClientServiceTest.java @@ -34,6 +34,7 @@ import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTED; import static androidx.test.espresso.intent.matcher.IntentMatchers.hasAction; import static androidx.test.espresso.intent.matcher.IntentMatchers.hasExtra; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.google.common.truth.Truth.assertThat; @@ -84,8 +85,6 @@ import org.mockito.InOrder; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.hamcrest.MockitoHamcrest; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.util.ArrayList; import java.util.Arrays; @@ -96,7 +95,7 @@ import java.util.Optional; @MediumTest @RunWith(AndroidJUnit4.class) public class HapClientServiceTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private AdapterService mAdapterService; @Mock private DatabaseManager mDatabaseManager; diff --git a/android/app/tests/unit/src/com/android/bluetooth/hap/HapClientStateMachineTest.java b/android/app/tests/unit/src/com/android/bluetooth/hap/HapClientStateMachineTest.java index 0b3cae7f33..f953dc47ff 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hap/HapClientStateMachineTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hap/HapClientStateMachineTest.java @@ -28,6 +28,7 @@ import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTING; import static androidx.test.espresso.intent.matcher.IntentMatchers.hasAction; import static androidx.test.espresso.intent.matcher.IntentMatchers.hasExtra; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.android.bluetooth.hap.HapClientStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED; import static com.android.bluetooth.hap.HapClientStateMachine.CONNECT_TIMEOUT; @@ -61,13 +62,11 @@ import org.junit.runner.RunWith; import org.mockito.InOrder; import org.mockito.Mock; import org.mockito.hamcrest.MockitoHamcrest; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; @SmallTest @RunWith(AndroidJUnit4.class) public class HapClientStateMachineTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private HapClientService mService; @Mock private HapClientNativeInterface mNativeInterface; diff --git a/android/app/tests/unit/src/com/android/bluetooth/hearingaid/HearingAidNativeInterfaceTest.java b/android/app/tests/unit/src/com/android/bluetooth/hearingaid/HearingAidNativeInterfaceTest.java index cfa466e9c0..0dff31a1c0 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hearingaid/HearingAidNativeInterfaceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hearingaid/HearingAidNativeInterfaceTest.java @@ -16,6 +16,7 @@ package com.android.bluetooth.hearingaid; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.google.common.truth.Truth.assertThat; @@ -37,12 +38,10 @@ import org.junit.Test; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.Mockito; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; public class HearingAidNativeInterfaceTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private HearingAidService mService; diff --git a/android/app/tests/unit/src/com/android/bluetooth/hearingaid/HearingAidServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/hearingaid/HearingAidServiceTest.java index 0b31461f27..dd17585929 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hearingaid/HearingAidServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hearingaid/HearingAidServiceTest.java @@ -30,6 +30,7 @@ import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTING; import static androidx.test.espresso.intent.matcher.IntentMatchers.hasAction; import static androidx.test.espresso.intent.matcher.IntentMatchers.hasExtra; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.google.common.truth.Truth.assertThat; @@ -76,8 +77,6 @@ import org.mockito.ArgumentCaptor; import org.mockito.InOrder; import org.mockito.Mock; import org.mockito.hamcrest.MockitoHamcrest; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.util.List; @@ -85,7 +84,7 @@ import java.util.List; @RunWith(AndroidJUnit4.class) public class HearingAidServiceTest { @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private AdapterService mAdapterService; @Mock private ActiveDeviceManager mActiveDeviceManager; diff --git a/android/app/tests/unit/src/com/android/bluetooth/hearingaid/HearingAidStateMachineTest.java b/android/app/tests/unit/src/com/android/bluetooth/hearingaid/HearingAidStateMachineTest.java index 3a011f0076..20feec9b8a 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hearingaid/HearingAidStateMachineTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hearingaid/HearingAidStateMachineTest.java @@ -25,6 +25,7 @@ import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTED; import static androidx.test.espresso.intent.matcher.IntentMatchers.hasAction; import static androidx.test.espresso.intent.matcher.IntentMatchers.hasExtra; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.google.common.truth.Truth.assertThat; @@ -55,13 +56,11 @@ import org.junit.runner.RunWith; import org.mockito.InOrder; import org.mockito.Mock; import org.mockito.hamcrest.MockitoHamcrest; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; @SmallTest @RunWith(AndroidJUnit4.class) public class HearingAidStateMachineTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private HearingAidService mService; @Mock private HearingAidNativeInterface mNativeInterface; diff --git a/android/app/tests/unit/src/com/android/bluetooth/hfp/AtPhonebookTest.java b/android/app/tests/unit/src/com/android/bluetooth/hfp/AtPhonebookTest.java index 7c36eb28ef..9126577e39 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hfp/AtPhonebookTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hfp/AtPhonebookTest.java @@ -16,6 +16,7 @@ package com.android.bluetooth.hfp; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.google.common.truth.Truth.assertThat; @@ -52,8 +53,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.Spy; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; @RunWith(AndroidJUnit4.class) public class AtPhonebookTest { @@ -61,7 +60,7 @@ public class AtPhonebookTest { private Context mTargetContext; private BluetoothDevice mDevice = getTestDevice(198); - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private AdapterService mAdapterService; @Mock private HeadsetNativeInterface mNativeInterface; diff --git a/android/app/tests/unit/src/com/android/bluetooth/hfp/BluetoothHeadsetBinderTest.java b/android/app/tests/unit/src/com/android/bluetooth/hfp/BluetoothHeadsetBinderTest.java index 08e0795cf4..4dffd067b5 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hfp/BluetoothHeadsetBinderTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hfp/BluetoothHeadsetBinderTest.java @@ -16,6 +16,7 @@ package com.android.bluetooth.hfp; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static org.mockito.Mockito.verify; @@ -28,11 +29,9 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; public class BluetoothHeadsetBinderTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private HeadsetService mService; diff --git a/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetPhoneStateTest.java b/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetPhoneStateTest.java index 14902997cc..6c5d267e54 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetPhoneStateTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetPhoneStateTest.java @@ -15,6 +15,7 @@ */ package com.android.bluetooth.hfp; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static org.junit.Assume.assumeTrue; @@ -41,14 +42,12 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; /** Unit test to verify various methods in {@link HeadsetPhoneState} */ @MediumTest @RunWith(AndroidJUnit4.class) public class HeadsetPhoneStateTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private HeadsetService mHeadsetService; @Mock private TelephonyManager mTelephonyManager; diff --git a/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetServiceAndStateMachineTest.java b/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetServiceAndStateMachineTest.java index 2425e28d3c..191a3c386f 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetServiceAndStateMachineTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetServiceAndStateMachineTest.java @@ -20,6 +20,7 @@ import static androidx.test.espresso.intent.matcher.IntentMatchers.hasAction; import static androidx.test.espresso.intent.matcher.IntentMatchers.hasData; import static androidx.test.espresso.intent.matcher.IntentMatchers.hasExtra; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.google.common.truth.Truth.assertThat; @@ -76,8 +77,6 @@ import org.mockito.InOrder; import org.mockito.Mock; import org.mockito.Spy; import org.mockito.hamcrest.MockitoHamcrest; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.util.ArrayList; import java.util.HashSet; @@ -89,7 +88,7 @@ import java.util.Set; public class HeadsetServiceAndStateMachineTest { @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Spy private HeadsetObjectsFactory mObjectsFactory = HeadsetObjectsFactory.getInstance(); @@ -181,7 +180,6 @@ public class HeadsetServiceAndStateMachineTest { mHeadsetService = new HeadsetService(mAdapterService, mNativeInterface, mTestLooper.getLooper()); - mHeadsetService.start(); mHeadsetService.setAvailable(true); verify(mObjectsFactory).makeSystemInterface(mHeadsetService); diff --git a/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetServiceTest.java index 3be9288ea3..456791d30c 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetServiceTest.java @@ -16,6 +16,7 @@ package com.android.bluetooth.hfp; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.google.common.truth.Truth.assertThat; @@ -70,8 +71,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.Spy; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.util.ArrayList; import java.util.HashMap; @@ -82,7 +81,7 @@ import java.util.Set; @MediumTest @RunWith(AndroidJUnit4.class) public class HeadsetServiceTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Spy private HeadsetObjectsFactory mObjectsFactory = HeadsetObjectsFactory.getInstance(); @@ -175,7 +174,6 @@ public class HeadsetServiceTest { doReturn(mSystemInterface).when(mObjectsFactory).makeSystemInterface(any()); HeadsetNativeInterface.setInstance(mNativeInterface); mHeadsetService = new HeadsetService(mAdapterService, mNativeInterface); - mHeadsetService.start(); mHeadsetService.setAvailable(true); verify(mObjectsFactory).makeSystemInterface(mHeadsetService); mHeadsetService.setForceScoAudio(true); diff --git a/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetStateMachineTest.java b/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetStateMachineTest.java index 45eca5bb0a..5d18f14119 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetStateMachineTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetStateMachineTest.java @@ -19,6 +19,7 @@ package com.android.bluetooth.hfp; import static android.Manifest.permission.BLUETOOTH_CONNECT; import static android.media.audio.Flags.FLAG_DEPRECATE_STREAM_BT_SCO; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.google.common.truth.Truth.assertThat; @@ -75,8 +76,6 @@ import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.Mockito; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.util.ArrayList; @@ -100,7 +99,7 @@ public class HeadsetStateMachineTest { private final BluetoothDevice mDevice = getTestDevice(87); private ArgumentCaptor<Intent> mIntentArgument = ArgumentCaptor.forClass(Intent.class); - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private AdapterService mAdapterService; @Mock private ActiveDeviceManager mActiveDeviceManager; diff --git a/android/app/tests/unit/src/com/android/bluetooth/hfpclient/HeadsetClientServiceBinderTest.java b/android/app/tests/unit/src/com/android/bluetooth/hfpclient/HeadsetClientServiceBinderTest.java index 1c79635e0c..5ae51566b7 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hfpclient/HeadsetClientServiceBinderTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hfpclient/HeadsetClientServiceBinderTest.java @@ -16,6 +16,7 @@ package com.android.bluetooth.hfpclient; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static org.mockito.Mockito.verify; @@ -31,13 +32,11 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; @SmallTest @RunWith(AndroidJUnit4.class) public class HeadsetClientServiceBinderTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private HeadsetClientService mService; diff --git a/android/app/tests/unit/src/com/android/bluetooth/hfpclient/HeadsetClientServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/hfpclient/HeadsetClientServiceTest.java index 4925087f7d..14f685b83f 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hfpclient/HeadsetClientServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hfpclient/HeadsetClientServiceTest.java @@ -18,6 +18,7 @@ package com.android.bluetooth.hfpclient; import static android.content.pm.PackageManager.FEATURE_WATCH; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.android.bluetooth.hfpclient.HeadsetClientService.MAX_HFP_SCO_VOICE_CALL_VOLUME; import static com.android.bluetooth.hfpclient.HeadsetClientService.MIN_HFP_SCO_VOICE_CALL_VOLUME; @@ -56,8 +57,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.Mockito; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.util.HashMap; import java.util.Map; @@ -66,7 +65,7 @@ import java.util.concurrent.TimeUnit; @MediumTest @RunWith(AndroidJUnit4.class) public class HeadsetClientServiceTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private AdapterService mAdapterService; @Mock private HeadsetClientStateMachine mStateMachine; diff --git a/android/app/tests/unit/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachineTest.java b/android/app/tests/unit/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachineTest.java index 9208c16414..43659c2422 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachineTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachineTest.java @@ -28,6 +28,7 @@ import static android.content.pm.PackageManager.FEATURE_WATCH; import static androidx.test.espresso.intent.matcher.IntentMatchers.hasAction; import static androidx.test.espresso.intent.matcher.IntentMatchers.hasExtra; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.android.bluetooth.hfpclient.HeadsetClientStateMachine.AT_OK; import static com.android.bluetooth.hfpclient.HeadsetClientStateMachine.ENTER_PRIVATE_MODE; @@ -79,8 +80,6 @@ import org.mockito.ArgumentCaptor; import org.mockito.InOrder; import org.mockito.Mock; import org.mockito.hamcrest.MockitoHamcrest; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.util.List; import java.util.Set; @@ -94,7 +93,7 @@ public class HeadsetClientStateMachineTest { private InOrder mInOrder; private TestLooper mTestLooper; - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); diff --git a/android/app/tests/unit/src/com/android/bluetooth/hfpclient/HfpNativeInterfaceTest.java b/android/app/tests/unit/src/com/android/bluetooth/hfpclient/HfpNativeInterfaceTest.java index f2e887db88..d47e70da86 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hfpclient/HfpNativeInterfaceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hfpclient/HfpNativeInterfaceTest.java @@ -16,13 +16,14 @@ package com.android.bluetooth.hfpclient; +import static com.android.bluetooth.TestUtils.MockitoRule; + import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.anyString; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import com.android.bluetooth.TestUtils; import com.android.bluetooth.btservice.AdapterService; import org.junit.After; @@ -31,13 +32,11 @@ import org.junit.Rule; import org.junit.Test; import org.mockito.ArgumentCaptor; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; public class HfpNativeInterfaceTest { private static final byte[] TEST_DEVICE_ADDRESS = new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock HeadsetClientService mService; @Mock AdapterService mAdapterService; @@ -45,17 +44,15 @@ public class HfpNativeInterfaceTest { private NativeInterface mNativeInterface; @Before - public void setUp() throws Exception { + public void setUp() { when(mService.isAvailable()).thenReturn(true); HeadsetClientService.setHeadsetClientService(mService); - TestUtils.setAdapterService(mAdapterService); - mNativeInterface = NativeInterface.getInstance(); + mNativeInterface = new NativeInterface(mAdapterService); } @After - public void tearDown() throws Exception { + public void tearDown() { HeadsetClientService.setHeadsetClientService(null); - TestUtils.clearAdapterService(mAdapterService); } @Test diff --git a/android/app/tests/unit/src/com/android/bluetooth/hfpclient/VendorCommandResponseProcessorTest.java b/android/app/tests/unit/src/com/android/bluetooth/hfpclient/VendorCommandResponseProcessorTest.java index a3979fde7a..776d713133 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hfpclient/VendorCommandResponseProcessorTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hfpclient/VendorCommandResponseProcessorTest.java @@ -16,6 +16,7 @@ package com.android.bluetooth.hfpclient; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.google.common.truth.Truth.assertThat; @@ -37,13 +38,11 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; @SmallTest @RunWith(AndroidJUnit4.class) public class VendorCommandResponseProcessorTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private NativeInterface mNativeInterface; @Mock private AdapterService mAdapterService; diff --git a/android/app/tests/unit/src/com/android/bluetooth/hfpclient/connserv/HeadsetClientServiceInterfaceTest.java b/android/app/tests/unit/src/com/android/bluetooth/hfpclient/connserv/HeadsetClientServiceInterfaceTest.java index e9ce70da33..11d5a02a56 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hfpclient/connserv/HeadsetClientServiceInterfaceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hfpclient/connserv/HeadsetClientServiceInterfaceTest.java @@ -16,6 +16,7 @@ package com.android.bluetooth.hfpclient; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.google.common.truth.Truth.assertThat; @@ -34,15 +35,13 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.util.List; import java.util.Set; @RunWith(AndroidJUnit4.class) public class HeadsetClientServiceInterfaceTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private HeadsetClientService mMockHeadsetClientService; diff --git a/android/app/tests/unit/src/com/android/bluetooth/hfpclient/connserv/HfpClientConnectionServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/hfpclient/connserv/HfpClientConnectionServiceTest.java index 3e746db382..7940c63073 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hfpclient/connserv/HfpClientConnectionServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hfpclient/connserv/HfpClientConnectionServiceTest.java @@ -16,12 +16,13 @@ package com.android.bluetooth.hfpclient; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; +import static com.android.bluetooth.TestUtils.mockGetSystemService; import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; @@ -51,8 +52,6 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.util.Arrays; import java.util.List; @@ -60,7 +59,7 @@ import java.util.List; @MediumTest @RunWith(AndroidJUnit4.class) public class HfpClientConnectionServiceTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private AdapterService mAdapterService; @Mock private HeadsetClientService mMockHeadsetClientService; @@ -78,9 +77,6 @@ public class HfpClientConnectionServiceTest { Context targetContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); TestUtils.setAdapterService(mAdapterService); - // Setup a mock TelecomManager so our calls don't start a real instance of this service - doNothing().when(mMockTelecomManager).addNewIncomingCall(any(), any()); - doNothing().when(mMockTelecomManager).addNewUnknownCall(any(), any()); // Set a mocked HeadsetClientService for testing so we can insure the right functions were // called through the service interface @@ -104,20 +100,18 @@ public class HfpClientConnectionServiceTest { .when(mMockResources) .getBoolean(R.bool.hfp_client_connection_service_support_emergency_call); - doReturn(Context.TELECOM_SERVICE) - .when(mHfpClientConnectionService) - .getSystemServiceName(TelecomManager.class); - doReturn(mMockTelecomManager) - .when(mHfpClientConnectionService) - .getSystemService(Context.TELECOM_SERVICE); + mockGetSystemService( + mHfpClientConnectionService, + Context.TELECOM_SERVICE, + TelecomManager.class, + mMockTelecomManager); doReturn(getPhoneAccount(mDevice)).when(mMockTelecomManager).getPhoneAccount(any()); - doReturn(Context.BLUETOOTH_SERVICE) - .when(mHfpClientConnectionService) - .getSystemServiceName(BluetoothManager.class); - doReturn(targetContext.getSystemService(BluetoothManager.class)) - .when(mHfpClientConnectionService) - .getSystemService(Context.BLUETOOTH_SERVICE); + mockGetSystemService( + mHfpClientConnectionService, + Context.BLUETOOTH_SERVICE, + BluetoothManager.class, + targetContext.getSystemService(BluetoothManager.class)); } @After diff --git a/android/app/tests/unit/src/com/android/bluetooth/hfpclient/connserv/HfpClientConnectionTest.java b/android/app/tests/unit/src/com/android/bluetooth/hfpclient/connserv/HfpClientConnectionTest.java index e7908d172c..83d36d8623 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hfpclient/connserv/HfpClientConnectionTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hfpclient/connserv/HfpClientConnectionTest.java @@ -16,6 +16,7 @@ package com.android.bluetooth.hfpclient; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.google.common.truth.Truth.assertThat; @@ -40,16 +41,14 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoJUnitRunner; -import org.mockito.junit.MockitoRule; import java.util.Set; @MediumTest @RunWith(MockitoJUnitRunner.class) public class HfpClientConnectionTest { - @Rule public MockitoRule rule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private HeadsetClientServiceInterface mMockServiceInterface; @Mock private Context mContext; diff --git a/android/app/tests/unit/src/com/android/bluetooth/hfpclient/connserv/HfpClientDeviceBlockTest.java b/android/app/tests/unit/src/com/android/bluetooth/hfpclient/connserv/HfpClientDeviceBlockTest.java index 8bad1df72d..5d6a5a3c9c 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hfpclient/connserv/HfpClientDeviceBlockTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hfpclient/connserv/HfpClientDeviceBlockTest.java @@ -16,7 +16,9 @@ package com.android.bluetooth.hfpclient; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; +import static com.android.bluetooth.TestUtils.mockGetSystemService; import static com.google.common.truth.Truth.assertThat; @@ -39,20 +41,17 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; @MediumTest @RunWith(AndroidJUnit4.class) public class HfpClientDeviceBlockTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private HeadsetClientService mHeadsetClientService; @Mock private HfpClientConnectionService mConnServ; @Mock private HeadsetClientServiceInterface mMockServiceInterface; @Mock private Context mApplicationContext; @Mock private Resources mResources; - @Mock private TelecomManager mTelecomManager; private static final String TEST_NUMBER = "000-111-2222"; private static final String KEY_SCO_STATE = "com.android.bluetooth.hfpclient.SCO_STATE"; @@ -75,9 +74,7 @@ public class HfpClientDeviceBlockTest { when(mConnServ.getApplicationContext()).thenReturn(mApplicationContext); when(mConnServ.getPackageName()).thenReturn(TEST_PACKAGE); - when(mConnServ.getSystemService(Context.TELECOM_SERVICE)).thenReturn(mTelecomManager); - when(mConnServ.getSystemServiceName(TelecomManager.class)) - .thenReturn(Context.TELECOM_SERVICE); + mockGetSystemService(mConnServ, Context.TELECOM_SERVICE, TelecomManager.class); when(mHeadsetClientService.isAvailable()).thenReturn(true); HeadsetClientService.setHeadsetClientService(mHeadsetClientService); diff --git a/android/app/tests/unit/src/com/android/bluetooth/hid/BluetoothHidDeviceBinderTest.java b/android/app/tests/unit/src/com/android/bluetooth/hid/BluetoothHidDeviceBinderTest.java index 68e223a621..52c220d86b 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hid/BluetoothHidDeviceBinderTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hid/BluetoothHidDeviceBinderTest.java @@ -16,6 +16,7 @@ package com.android.bluetooth.hid; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static org.mockito.Mockito.any; @@ -34,11 +35,9 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; public class BluetoothHidDeviceBinderTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private HidDeviceService mService; diff --git a/android/app/tests/unit/src/com/android/bluetooth/hid/HidDeviceNativeInterfaceTest.java b/android/app/tests/unit/src/com/android/bluetooth/hid/HidDeviceNativeInterfaceTest.java index 0139960b57..787eaacb86 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hid/HidDeviceNativeInterfaceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hid/HidDeviceNativeInterfaceTest.java @@ -16,6 +16,8 @@ package com.android.bluetooth.hid; +import static com.android.bluetooth.TestUtils.MockitoRule; + import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; @@ -31,13 +33,11 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; public class HidDeviceNativeInterfaceTest { private static final byte[] TEST_DEVICE_ADDRESS = new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock HidDeviceService mService; @Mock AdapterService mAdapterService; diff --git a/android/app/tests/unit/src/com/android/bluetooth/hid/HidDeviceTest.java b/android/app/tests/unit/src/com/android/bluetooth/hid/HidDeviceTest.java index 2bd8e93171..93bddc96f3 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hid/HidDeviceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hid/HidDeviceTest.java @@ -25,6 +25,7 @@ import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTING; import static androidx.test.espresso.intent.matcher.IntentMatchers.hasAction; import static androidx.test.espresso.intent.matcher.IntentMatchers.hasExtra; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.android.bluetooth.TestUtils.mockGetSystemService; @@ -72,13 +73,11 @@ import org.junit.runner.RunWith; import org.mockito.InOrder; import org.mockito.Mock; import org.mockito.hamcrest.MockitoHamcrest; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; @MediumTest @RunWith(AndroidJUnit4.class) public class HidDeviceTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private AdapterService mAdapterService; @Mock private DatabaseManager mDatabaseManager; diff --git a/android/app/tests/unit/src/com/android/bluetooth/hid/HidHostServiceBinderTest.java b/android/app/tests/unit/src/com/android/bluetooth/hid/HidHostServiceBinderTest.java index f48791edd1..74f80c6fdb 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hid/HidHostServiceBinderTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hid/HidHostServiceBinderTest.java @@ -16,6 +16,7 @@ package com.android.bluetooth.hid; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static org.mockito.Mockito.verify; @@ -32,14 +33,12 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; @SmallTest @RunWith(AndroidJUnit4.class) public class HidHostServiceBinderTest { @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private HidHostService mService; diff --git a/android/app/tests/unit/src/com/android/bluetooth/hid/HidHostServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/hid/HidHostServiceTest.java index 272440c275..bc08c8d820 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hid/HidHostServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hid/HidHostServiceTest.java @@ -22,6 +22,7 @@ import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_ALLOWED; import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_FORBIDDEN; import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_UNKNOWN; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.google.common.truth.Truth.assertThat; @@ -46,15 +47,13 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.util.List; @MediumTest @RunWith(AndroidJUnit4.class) public class HidHostServiceTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private AdapterService mAdapterService; @Mock private DatabaseManager mDatabaseManager; diff --git a/android/app/tests/unit/src/com/android/bluetooth/le_audio/ContentControlIdKeeperTest.java b/android/app/tests/unit/src/com/android/bluetooth/le_audio/ContentControlIdKeeperTest.java index 500e697502..0fc41d3d0c 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/le_audio/ContentControlIdKeeperTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/le_audio/ContentControlIdKeeperTest.java @@ -16,6 +16,8 @@ package com.android.bluetooth.le_audio; +import static com.android.bluetooth.TestUtils.MockitoRule; + import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.*; @@ -35,8 +37,6 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.util.Map; import java.util.UUID; @@ -44,7 +44,7 @@ import java.util.UUID; @MediumTest @RunWith(AndroidJUnit4.class) public class ContentControlIdKeeperTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock ServiceFactory mServiceFactoryMock; @Mock LeAudioService mLeAudioServiceMock; diff --git a/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioBinderTest.java b/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioBinderTest.java index 8ff3492dfb..923a9cb7bc 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioBinderTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioBinderTest.java @@ -16,6 +16,7 @@ package com.android.bluetooth.le_audio; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static org.mockito.Mockito.verify; @@ -38,14 +39,12 @@ import org.junit.Rule; import org.junit.Test; import org.mockito.Mock; import org.mockito.Mockito; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.util.UUID; public class LeAudioBinderTest { @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private LeAudioService mService; diff --git a/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioBroadcastServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioBroadcastServiceTest.java index b7d3e5f947..d717cb9414 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioBroadcastServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioBroadcastServiceTest.java @@ -30,6 +30,7 @@ import static android.bluetooth.IBluetoothLeAudio.LE_AUDIO_GROUP_ID_INVALID; import static androidx.test.espresso.intent.matcher.IntentMatchers.hasAction; import static androidx.test.espresso.intent.matcher.IntentMatchers.hasExtra; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.android.bluetooth.TestUtils.mockGetSystemService; import static com.android.bluetooth.bass_client.BassConstants.INVALID_BROADCAST_ID; @@ -108,8 +109,6 @@ import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.Spy; import org.mockito.hamcrest.MockitoHamcrest; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.util.ArrayList; import java.util.List; @@ -118,7 +117,7 @@ import java.util.List; @RunWith(AndroidJUnit4.class) public class LeAudioBroadcastServiceTest { @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private ActiveDeviceManager mActiveDeviceManager; @Mock private AdapterService mAdapterService; diff --git a/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioBroadcasterNativeInterfaceTest.java b/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioBroadcasterNativeInterfaceTest.java index 889a8cdcbf..d74b6caf53 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioBroadcasterNativeInterfaceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioBroadcasterNativeInterfaceTest.java @@ -16,6 +16,8 @@ package com.android.bluetooth.le_audio; +import static com.android.bluetooth.TestUtils.MockitoRule; + import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.verify; @@ -32,12 +34,10 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; @RunWith(AndroidJUnit4.class) public class LeAudioBroadcasterNativeInterfaceTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private LeAudioService mMockService; diff --git a/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioNativeInterfaceTest.java b/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioNativeInterfaceTest.java index c6e8cf3338..03d85dfc4d 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioNativeInterfaceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioNativeInterfaceTest.java @@ -16,6 +16,8 @@ package com.android.bluetooth.le_audio; +import static com.android.bluetooth.TestUtils.MockitoRule; + import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.verify; @@ -33,12 +35,10 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; @RunWith(AndroidJUnit4.class) public class LeAudioNativeInterfaceTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private LeAudioService mMockService; 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 c186e50f25..641314d74f 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 @@ -30,6 +30,7 @@ import static android.bluetooth.IBluetoothLeAudio.LE_AUDIO_GROUP_ID_INVALID; import static androidx.test.espresso.intent.matcher.IntentMatchers.hasAction; import static androidx.test.espresso.intent.matcher.IntentMatchers.hasExtra; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.android.bluetooth.TestUtils.mockGetSystemService; @@ -109,8 +110,6 @@ import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.Spy; import org.mockito.hamcrest.MockitoHamcrest; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.util.ArrayList; import java.util.HashSet; @@ -121,7 +120,7 @@ import java.util.Objects; @RunWith(AndroidJUnit4.class) public class LeAudioServiceTest { @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private AdapterService mAdapterService; @Mock private GattService mGattService; diff --git a/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioStateMachineTest.java b/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioStateMachineTest.java index 1cd378eef5..b58868cff8 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioStateMachineTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioStateMachineTest.java @@ -17,6 +17,7 @@ package com.android.bluetooth.le_audio; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.android.bluetooth.le_audio.LeAudioStateMachine.CONNECT; import static com.android.bluetooth.le_audio.LeAudioStateMachine.DISCONNECT; @@ -53,8 +54,6 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; @MediumTest @RunWith(AndroidJUnit4.class) @@ -64,7 +63,7 @@ public class LeAudioStateMachineTest { private final BluetoothDevice mDevice = getTestDevice(68); private static final int TIMEOUT_MS = 1000; - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); @Mock private AdapterService mAdapterService; diff --git a/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioTmapGattServerTest.java b/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioTmapGattServerTest.java index 29116ced0f..abb4ddd7a7 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioTmapGattServerTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioTmapGattServerTest.java @@ -20,6 +20,8 @@ import static android.bluetooth.BluetoothGattCharacteristic.FORMAT_UINT16; import static android.bluetooth.BluetoothGattCharacteristic.PERMISSION_READ; import static android.bluetooth.BluetoothGattCharacteristic.PROPERTY_READ; +import static com.android.bluetooth.TestUtils.MockitoRule; + import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertThrows; @@ -41,8 +43,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; @MediumTest @RunWith(AndroidJUnit4.class) @@ -50,7 +50,7 @@ public class LeAudioTmapGattServerTest { private static final int TEST_ROLE_MASK = LeAudioTmapGattServer.TMAP_ROLE_FLAG_CG | LeAudioTmapGattServer.TMAP_ROLE_FLAG_UMS; - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private LeAudioTmapGattServer.BluetoothGattServerProxy mGattServerProxy; diff --git a/android/app/tests/unit/src/com/android/bluetooth/le_scan/AppScanStatsTest.java b/android/app/tests/unit/src/com/android/bluetooth/le_scan/AppScanStatsTest.java index d243374282..d7dd369ced 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/le_scan/AppScanStatsTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/le_scan/AppScanStatsTest.java @@ -16,6 +16,7 @@ package com.android.bluetooth.le_scan; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.Utils.getSystemClock; import static com.google.common.truth.Truth.assertThat; @@ -39,8 +40,6 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.util.ArrayList; import java.util.List; @@ -50,7 +49,7 @@ import java.util.List; @RunWith(AndroidJUnit4.class) public class AppScanStatsTest { @Rule public final ServiceTestRule mServiceRule = new ServiceTestRule(); - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private ScannerMap map; @Mock private ScanController mMockScanController; diff --git a/android/app/tests/unit/src/com/android/bluetooth/le_scan/BatchScanThrottlerTest.java b/android/app/tests/unit/src/com/android/bluetooth/le_scan/BatchScanThrottlerTest.java index 67f32c4f0c..5e8f59fef5 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/le_scan/BatchScanThrottlerTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/le_scan/BatchScanThrottlerTest.java @@ -18,6 +18,7 @@ package com.android.bluetooth.le_scan; import static android.bluetooth.le.ScanSettings.SCAN_MODE_BALANCED; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.le_scan.ScanController.DEFAULT_REPORT_DELAY_FLOOR; import static com.google.common.truth.Truth.assertThat; @@ -37,8 +38,6 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.time.Duration; import java.util.Collections; @@ -51,7 +50,7 @@ import java.util.stream.LongStream; @RunWith(TestParameterInjector.class) public class BatchScanThrottlerTest { @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); private FakeTimeProvider mTimeProvider; diff --git a/android/app/tests/unit/src/com/android/bluetooth/le_scan/PeriodicScanManagerTest.java b/android/app/tests/unit/src/com/android/bluetooth/le_scan/PeriodicScanManagerTest.java index 8b8d2e2beb..e05daddc57 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/le_scan/PeriodicScanManagerTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/le_scan/PeriodicScanManagerTest.java @@ -16,6 +16,8 @@ package com.android.bluetooth.le_scan; +import static com.android.bluetooth.TestUtils.MockitoRule; + import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.any; @@ -47,14 +49,12 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; /** Test cases for {@link PeriodicScanManagerTest}. */ @SmallTest @RunWith(AndroidJUnit4.class) public class PeriodicScanManagerTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private PeriodicScanNativeInterface mPeriodicScanNativeInterface; @Mock private AdapterService mAdapterService; diff --git a/android/app/tests/unit/src/com/android/bluetooth/le_scan/ScanControllerTest.java b/android/app/tests/unit/src/com/android/bluetooth/le_scan/ScanControllerTest.java index fbc47f983f..d25f67b2d8 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/le_scan/ScanControllerTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/le_scan/ScanControllerTest.java @@ -16,6 +16,7 @@ package com.android.bluetooth.le_scan; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.google.common.truth.Truth.assertThat; @@ -69,8 +70,6 @@ import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.ArgumentMatcher; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.util.ArrayList; import java.util.Collections; @@ -81,7 +80,7 @@ import java.util.Set; @SmallTest @RunWith(TestParameterInjector.class) public class ScanControllerTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); @Mock private ScannerMap mScannerMap; diff --git a/android/app/tests/unit/src/com/android/bluetooth/le_scan/ScanManagerTest.java b/android/app/tests/unit/src/com/android/bluetooth/le_scan/ScanManagerTest.java index 6c9e5c0927..2351accf89 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/le_scan/ScanManagerTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/le_scan/ScanManagerTest.java @@ -32,6 +32,7 @@ import static android.bluetooth.le.ScanSettings.SCAN_MODE_OPPORTUNISTIC; import static android.bluetooth.le.ScanSettings.SCAN_MODE_SCREEN_OFF; import static android.bluetooth.le.ScanSettings.SCAN_MODE_SCREEN_OFF_BALANCED; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.btservice.AdapterService.DeviceConfigListener.DEFAULT_SCAN_DOWNGRADE_DURATION_BT_CONNECTING_MILLIS; import static com.android.bluetooth.btservice.AdapterService.DeviceConfigListener.DEFAULT_SCAN_TIMEOUT_MILLIS; import static com.android.bluetooth.btservice.AdapterService.DeviceConfigListener.DEFAULT_SCAN_UPGRADE_DURATION_MILLIS; @@ -110,8 +111,6 @@ import org.mockito.InOrder; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.Spy; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.time.Duration; import java.util.ArrayList; @@ -125,7 +124,7 @@ import java.util.UUID; @RunWith(TestParameterInjector.class) public class ScanManagerTest { @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private AdapterService mAdapterService; @Mock private BluetoothAdapterProxy mBluetoothAdapterProxy; @@ -2025,6 +2024,9 @@ public class ScanManagerTest { sendMessageWaitForProcessed(createStartStopScanMessage(false, clientCoded)); verify(mScanNativeInterface, atLeastOnce()).gattClientScan(false); + verify(mScanNativeInterface, never()) + .gattSetScanParameters( + anyInt(), anyInt(), anyInt(), anyInt(), anyInt(), anyInt(), eq(0)); } @Test diff --git a/android/app/tests/unit/src/com/android/bluetooth/le_scan/ScannerMapTest.java b/android/app/tests/unit/src/com/android/bluetooth/le_scan/ScannerMapTest.java index 2259c9a54f..9bee3680c3 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/le_scan/ScannerMapTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/le_scan/ScannerMapTest.java @@ -16,6 +16,8 @@ package com.android.bluetooth.le_scan; +import static com.android.bluetooth.TestUtils.MockitoRule; + import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.anyInt; @@ -44,8 +46,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.Spy; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.util.UUID; @@ -57,7 +57,7 @@ public class ScannerMapTest { private static final int UID = 12345; private static final int SCANNER_ID = 321; - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private AdapterService mAdapterService; @Mock private PackageManager mMockPackageManager; diff --git a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapContentObserverTest.java b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapContentObserverTest.java index 44cea7dd97..520c678294 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapContentObserverTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapContentObserverTest.java @@ -16,6 +16,9 @@ package com.android.bluetooth.map; +import static com.android.bluetooth.TestUtils.MockitoRule; +import static com.android.bluetooth.TestUtils.mockGetSystemService; + import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertThrows; @@ -62,8 +65,6 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.Spy; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.text.SimpleDateFormat; import java.time.Instant; @@ -121,7 +122,7 @@ public class BluetoothMapContentObserverTest { static final int TEST_PRIORITY = 1; static final int TEST_LAST_ONLINE = 1; - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); @Mock private BluetoothMnsObexClient mClient; @@ -183,11 +184,9 @@ public class BluetoothMapContentObserverTest { // Functions that get called when BluetoothMapContentObserver is created when(mUserService.isUserUnlocked()).thenReturn(true); when(mContext.getContentResolver()).thenReturn(mMockContentResolver); - when(mContext.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephonyManager); - when(mContext.getSystemServiceName(TelephonyManager.class)) - .thenReturn(Context.TELEPHONY_SERVICE); - when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserService); - when(mContext.getSystemServiceName(UserManager.class)).thenReturn(Context.USER_SERVICE); + mockGetSystemService( + mContext, Context.TELEPHONY_SERVICE, TelephonyManager.class, mTelephonyManager); + mockGetSystemService(mContext, Context.USER_SERVICE, UserManager.class, mUserService); when(mInstance.getMasId()).thenReturn(TEST_ID); mObserver = new BluetoothMapContentObserver(mContext, mClient, mInstance, null, true); diff --git a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapContentTest.java b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapContentTest.java index 99d69c8084..691ff23e95 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapContentTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapContentTest.java @@ -16,6 +16,9 @@ package com.android.bluetooth.map; +import static com.android.bluetooth.TestUtils.MockitoRule; +import static com.android.bluetooth.TestUtils.mockGetSystemService; + import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertThrows; @@ -59,8 +62,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.Spy; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.io.ByteArrayInputStream; import java.io.FileDescriptor; @@ -113,7 +114,7 @@ public class BluetoothMapContentTest { private static final String TEST_RECEPTION_STATUS = "complete"; private static final String TEST_EMAIL = "test@google.com"; - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private BluetoothMapAccountItem mAccountItem; @Mock private BluetoothMapMasInstance mMasInstance; @@ -377,9 +378,8 @@ public class BluetoothMapContentTest { @Test public void setFilterInfo() { - when(mContext.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephonyManager); - when(mContext.getSystemServiceName(TelephonyManager.class)) - .thenReturn(Context.TELEPHONY_SERVICE); + mockGetSystemService( + mContext, Context.TELEPHONY_SERVICE, TelephonyManager.class, mTelephonyManager); when(mTelephonyManager.getPhoneType()).thenReturn(TelephonyManager.PHONE_TYPE_GSM); mContent.setFilterInfo(mInfo); diff --git a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapConvoContactElementTest.java b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapConvoContactElementTest.java index 229a3a5643..08529c26ba 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapConvoContactElementTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapConvoContactElementTest.java @@ -16,6 +16,8 @@ package com.android.bluetooth.map; +import static com.android.bluetooth.TestUtils.MockitoRule; + import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.when; @@ -30,8 +32,6 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserFactory; import org.xmlpull.v1.XmlSerializer; @@ -54,7 +54,7 @@ public class BluetoothMapConvoContactElementTest { private final SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmss"); - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private MapContact mMapContact; diff --git a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapMasInstanceTest.java b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapMasInstanceTest.java index 19dda41311..b0239dfd02 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapMasInstanceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapMasInstanceTest.java @@ -16,6 +16,8 @@ package com.android.bluetooth.map; +import static com.android.bluetooth.TestUtils.MockitoRule; + import static com.google.common.truth.Truth.assertThat; import android.content.Context; @@ -30,8 +32,6 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; @SmallTest @RunWith(AndroidJUnit4.class) @@ -49,7 +49,7 @@ public class BluetoothMapMasInstanceTest { private BluetoothMapAccountItem mAccountItem; - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private Context mContext; @Mock private BluetoothMapService mMapService; diff --git a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapObexServerTest.java b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapObexServerTest.java index 19dae89d5d..b2c3d00c54 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapObexServerTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapObexServerTest.java @@ -16,6 +16,8 @@ package com.android.bluetooth.map; +import static com.android.bluetooth.TestUtils.MockitoRule; + import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertThrows; @@ -47,8 +49,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.Spy; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; @SmallTest @RunWith(AndroidJUnit4.class) @@ -69,7 +69,7 @@ public class BluetoothMapObexServerTest { private BluetoothMapObexServer mObexServer; private BluetoothMapAppParams mParams; - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private Context mContext; @Mock private BluetoothMapService mMapService; diff --git a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapServiceBinderTest.java b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapServiceBinderTest.java index 17fd509479..72a3c75168 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapServiceBinderTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapServiceBinderTest.java @@ -16,6 +16,7 @@ package com.android.bluetooth.map; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static org.mockito.Mockito.verify; @@ -31,13 +32,11 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; @SmallTest @RunWith(AndroidJUnit4.class) public class BluetoothMapServiceBinderTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private BluetoothMapService mService; diff --git a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapServiceTest.java index c160487143..c8def49656 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapServiceTest.java @@ -15,6 +15,7 @@ */ package com.android.bluetooth.map; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.android.bluetooth.TestUtils.mockGetSystemService; @@ -42,8 +43,6 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; @MediumTest @RunWith(AndroidJUnit4.class) @@ -53,7 +52,7 @@ public class BluetoothMapServiceTest { private final Context mTargetContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private AdapterService mAdapterService; @Mock private DatabaseManager mDatabaseManager; diff --git a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapSmsPduTest.java b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapSmsPduTest.java index cb5832958d..285d056242 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapSmsPduTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapSmsPduTest.java @@ -18,6 +18,9 @@ package com.android.bluetooth.map; import static android.content.pm.PackageManager.FEATURE_TELEPHONY_MESSAGING; +import static com.android.bluetooth.TestUtils.MockitoRule; +import static com.android.bluetooth.TestUtils.mockGetSystemService; + import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertThrows; @@ -40,8 +43,6 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.io.ByteArrayInputStream; import java.io.InputStream; @@ -61,9 +62,9 @@ public class BluetoothMapSmsPduTest { private int TEST_ENCODING; private int TEST_LANGUAGE_TABLE; - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); - @Mock private Context mTargetContext; + @Mock private Context mContext; @Mock private TelephonyManager mTelephonyManager; @Before @@ -71,9 +72,8 @@ public class BluetoothMapSmsPduTest { PackageManager packageManager = InstrumentationRegistry.getInstrumentation().getTargetContext().getPackageManager(); assumeTrue(packageManager.hasSystemFeature(FEATURE_TELEPHONY_MESSAGING)); - when(mTargetContext.getSystemServiceName(TelephonyManager.class)) - .thenReturn("TELEPHONY_SERVICE"); - when(mTargetContext.getSystemService("TELEPHONY_SERVICE")).thenReturn(mTelephonyManager); + mockGetSystemService( + mContext, Context.TELEPHONY_SERVICE, TelephonyManager.class, mTelephonyManager); int[] ted = SmsMessage.calculateLength((CharSequence) TEST_TEXT, false); TEST_ENCODING = ted[3]; @@ -111,8 +111,7 @@ public class BluetoothMapSmsPduTest { when(mTelephonyManager.getCurrentPhoneType()).thenReturn(TelephonyManager.PHONE_TYPE_GSM); List<SmsPdu> pdus = - BluetoothMapSmsPdu.getSubmitPdus( - mTargetContext, TEST_TEXT_WITH_TWO_SMS_PARTS, null); + BluetoothMapSmsPdu.getSubmitPdus(mContext, TEST_TEXT_WITH_TWO_SMS_PARTS, null); assertThat(pdus).hasSize(2); assertThat(pdus.get(0).getType()).isEqualTo(BluetoothMapSmsPdu.SMS_TYPE_GSM); @@ -137,7 +136,7 @@ public class BluetoothMapSmsPduTest { public void getSubmitPdus_withTypeCDMA() throws Exception { when(mTelephonyManager.getCurrentPhoneType()).thenReturn(TelephonyManager.PHONE_TYPE_CDMA); - List<SmsPdu> pdus = BluetoothMapSmsPdu.getSubmitPdus(mTargetContext, TEST_TEXT, null); + List<SmsPdu> pdus = BluetoothMapSmsPdu.getSubmitPdus(mContext, TEST_TEXT, null); assertThat(pdus).hasSize(1); assertThat(pdus.get(0).getType()).isEqualTo(BluetoothMapSmsPdu.SMS_TYPE_CDMA); @@ -162,7 +161,7 @@ public class BluetoothMapSmsPduTest { List<SmsPdu> pdus = BluetoothMapSmsPdu.getDeliverPdus( - mTargetContext, TEST_TEXT, TEST_DESTINATION_ADDRESS, TEST_DATE); + mContext, TEST_TEXT, TEST_DESTINATION_ADDRESS, TEST_DATE); assertThat(pdus).hasSize(1); assertThat(pdus.get(0).getType()).isEqualTo(BluetoothMapSmsPdu.SMS_TYPE_GSM); @@ -189,7 +188,7 @@ public class BluetoothMapSmsPduTest { List<SmsPdu> pdus = BluetoothMapSmsPdu.getDeliverPdus( - mTargetContext, TEST_TEXT, TEST_DESTINATION_ADDRESS, TEST_DATE); + mContext, TEST_TEXT, TEST_DESTINATION_ADDRESS, TEST_DATE); assertThat(pdus).hasSize(1); assertThat(pdus.get(0).getType()).isEqualTo(BluetoothMapSmsPdu.SMS_TYPE_CDMA); diff --git a/android/app/tests/unit/src/com/android/bluetooth/map/EventTest.java b/android/app/tests/unit/src/com/android/bluetooth/map/EventTest.java index 4ba945ead9..d1962fc37b 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/map/EventTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/map/EventTest.java @@ -16,6 +16,8 @@ package com.android.bluetooth.map; +import static com.android.bluetooth.TestUtils.mockGetSystemService; + import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.mock; @@ -72,17 +74,14 @@ public class EventTest { new BluetoothMapContentObserverTest.ExceptionTestProvider(mockContext); mockResolver.addProvider("sms", mockProvider); - TelephonyManager mockTelephony = mock(TelephonyManager.class); UserManager mockUserService = mock(UserManager.class); BluetoothMapMasInstance mockMas = mock(BluetoothMapMasInstance.class); // Functions that get called when BluetoothMapContentObserver is created when(mockUserService.isUserUnlocked()).thenReturn(true); when(mockContext.getContentResolver()).thenReturn(mockResolver); - when(mockContext.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mockTelephony); - when(mockContext.getSystemServiceName(TelephonyManager.class)) - .thenReturn(Context.TELEPHONY_SERVICE); - when(mockContext.getSystemService(Context.USER_SERVICE)).thenReturn(mockUserService); + mockGetSystemService(mockContext, Context.TELEPHONY_SERVICE, TelephonyManager.class); + mockGetSystemService(mockContext, Context.USER_SERVICE, UserManager.class, mockUserService); mObserver = new BluetoothMapContentObserver(mockContext, null, mockMas, null, true); mEvent = mObserver.new Event(TEST_EVENT_TYPE, TEST_HANDLE, TEST_FOLDER, TEST_TYPE); } diff --git a/android/app/tests/unit/src/com/android/bluetooth/map/SmsMmsContactsTest.java b/android/app/tests/unit/src/com/android/bluetooth/map/SmsMmsContactsTest.java index bcf9a266a8..eea885ba4c 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/map/SmsMmsContactsTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/map/SmsMmsContactsTest.java @@ -16,6 +16,8 @@ package com.android.bluetooth.map; +import static com.android.bluetooth.TestUtils.MockitoRule; + import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.any; @@ -36,8 +38,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.Spy; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; @SmallTest @RunWith(AndroidJUnit4.class) @@ -48,7 +48,7 @@ public class SmsMmsContactsTest { private static final String TEST_PHONE = "test_phone"; private static final String TEST_CONTACT_NAME_FILTER = "test_contact_name_filter"; - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private ContentResolver mResolver; @Spy private BluetoothMethodProxy mMapMethodProxy = BluetoothMethodProxy.getInstance(); diff --git a/android/app/tests/unit/src/com/android/bluetooth/mapapi/BluetoothMapEmailProviderTest.java b/android/app/tests/unit/src/com/android/bluetooth/mapapi/BluetoothMapEmailProviderTest.java index 95ee079bd0..46c9d8a9cc 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/mapapi/BluetoothMapEmailProviderTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/mapapi/BluetoothMapEmailProviderTest.java @@ -16,6 +16,8 @@ package com.android.bluetooth.mapapi; +import static com.android.bluetooth.TestUtils.MockitoRule; + import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; @@ -40,8 +42,6 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Spy; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.io.FileInputStream; import java.io.FileOutputStream; @@ -57,7 +57,7 @@ public class BluetoothMapEmailProviderTest { private Context mContext; - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Spy private BluetoothMapEmailProvider mProvider = new TestBluetoothMapEmailProvider(); diff --git a/android/app/tests/unit/src/com/android/bluetooth/mapapi/BluetoothMapIMProviderTest.java b/android/app/tests/unit/src/com/android/bluetooth/mapapi/BluetoothMapIMProviderTest.java index edb87aae5c..3cf4856ef1 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/mapapi/BluetoothMapIMProviderTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/mapapi/BluetoothMapIMProviderTest.java @@ -16,6 +16,8 @@ package com.android.bluetooth.mapapi; +import static com.android.bluetooth.TestUtils.MockitoRule; + import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; @@ -46,8 +48,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mockito; import org.mockito.Spy; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.time.Instant; import java.util.AbstractMap; @@ -68,7 +68,7 @@ public class BluetoothMapIMProviderTest { private Context mContext; - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Spy private BluetoothMapIMProvider mProvider = new TestBluetoothMapIMProvider(); diff --git a/android/app/tests/unit/src/com/android/bluetooth/mapclient/MapClientContentTest.java b/android/app/tests/unit/src/com/android/bluetooth/mapclient/MapClientContentTest.java index 5906b34264..c2e4d92c8f 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/mapclient/MapClientContentTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/mapclient/MapClientContentTest.java @@ -16,7 +16,9 @@ package com.android.bluetooth.mapclient; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; +import static com.android.bluetooth.TestUtils.mockGetSystemService; import static com.google.common.truth.Truth.assertThat; @@ -58,8 +60,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.Mockito; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.util.Arrays; import java.util.HashMap; @@ -86,7 +86,7 @@ public class MapClientContentTest { private MapClientContent mMapClientContent; - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private Context mMockContext; @Mock private MapClientContent.Callbacks mCallbacks; @@ -112,10 +112,11 @@ public class MapClientContentTest { mMockContentResolver.addProvider("mms-sms", mMockThreadContentProvider); when(mMockContext.getContentResolver()).thenReturn(mMockContentResolver); - when(mMockContext.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE)) - .thenReturn(mMockSubscriptionManager); - when(mMockContext.getSystemServiceName(SubscriptionManager.class)) - .thenReturn(Context.TELEPHONY_SUBSCRIPTION_SERVICE); + mockGetSystemService( + mMockContext, + Context.TELEPHONY_SUBSCRIPTION_SERVICE, + SubscriptionManager.class, + mMockSubscriptionManager); when(mMockSubscriptionManager.getActiveSubscriptionInfoList()) .thenReturn(Arrays.asList(mMockSubscription)); diff --git a/android/app/tests/unit/src/com/android/bluetooth/mapclient/MapClientServiceBinderTest.java b/android/app/tests/unit/src/com/android/bluetooth/mapclient/MapClientServiceBinderTest.java index a0177a7c65..431314a7af 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/mapclient/MapClientServiceBinderTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/mapclient/MapClientServiceBinderTest.java @@ -15,6 +15,7 @@ */ package com.android.bluetooth.mapclient; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static org.mockito.Mockito.verify; @@ -31,13 +32,11 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; @MediumTest @RunWith(AndroidJUnit4.class) public class MapClientServiceBinderTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private MapClientService mService; diff --git a/android/app/tests/unit/src/com/android/bluetooth/mapclient/MapClientServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/mapclient/MapClientServiceTest.java index 82d073690c..63cce22b98 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/mapclient/MapClientServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/mapclient/MapClientServiceTest.java @@ -19,6 +19,7 @@ import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_ALLOWED; import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_FORBIDDEN; import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_UNKNOWN; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.google.common.truth.Truth.assertThat; @@ -56,8 +57,6 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.util.ArrayList; import java.util.List; @@ -65,7 +64,7 @@ import java.util.List; @MediumTest @RunWith(AndroidJUnit4.class) public class MapClientServiceTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private AdapterService mAdapterService; @Mock private DatabaseManager mDatabaseManager; diff --git a/android/app/tests/unit/src/com/android/bluetooth/mapclient/MapClientStateMachineTest.java b/android/app/tests/unit/src/com/android/bluetooth/mapclient/MapClientStateMachineTest.java index 2bd857c6a6..3c8705172a 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/mapclient/MapClientStateMachineTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/mapclient/MapClientStateMachineTest.java @@ -29,6 +29,7 @@ import static androidx.test.espresso.intent.matcher.IntentMatchers.hasAction; import static androidx.test.espresso.intent.matcher.IntentMatchers.hasExtra; import static androidx.test.espresso.intent.matcher.IntentMatchers.hasPackage; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.google.common.truth.Truth.assertThat; @@ -88,8 +89,6 @@ import org.mockito.InOrder; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.hamcrest.MockitoHamcrest; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import platform.test.runner.parameterized.ParameterizedAndroidJunit4; import platform.test.runner.parameterized.Parameters; @@ -106,7 +105,7 @@ import java.util.concurrent.TimeUnit; @RunWith(ParameterizedAndroidJunit4.class) public class MapClientStateMachineTest { @Rule public final SetFlagsRule mSetFlagsRule; - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Rule public final ServiceTestRule mServiceRule = new ServiceTestRule(); @Mock private AdapterService mAdapterService; diff --git a/android/app/tests/unit/src/com/android/bluetooth/mapclient/MnsObexServerTest.java b/android/app/tests/unit/src/com/android/bluetooth/mapclient/MnsObexServerTest.java index 1ed1286397..3979e3cc60 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/mapclient/MnsObexServerTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/mapclient/MnsObexServerTest.java @@ -16,6 +16,8 @@ package com.android.bluetooth.mapclient; +import static com.android.bluetooth.TestUtils.MockitoRule; + import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.any; @@ -35,8 +37,6 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.io.ByteArrayInputStream; import java.io.DataInputStream; @@ -45,7 +45,7 @@ import java.io.DataInputStream; @RunWith(AndroidJUnit4.class) public class MnsObexServerTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock MceStateMachine mStateMachine; diff --git a/android/app/tests/unit/src/com/android/bluetooth/mcp/McpServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/mcp/McpServiceTest.java index 43dce5fbe7..e3663859fc 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/mcp/McpServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/mcp/McpServiceTest.java @@ -17,6 +17,7 @@ package com.android.bluetooth.mcp; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.google.common.truth.Truth.assertThat; @@ -36,13 +37,11 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; @MediumTest @RunWith(AndroidJUnit4.class) public class McpServiceTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private MediaControlProfile mMediaControlProfile; @Mock private Context mContext; diff --git a/android/app/tests/unit/src/com/android/bluetooth/mcp/MediaControlGattServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/mcp/MediaControlGattServiceTest.java index 8534ee2e7c..bb53310b80 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/mcp/MediaControlGattServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/mcp/MediaControlGattServiceTest.java @@ -17,6 +17,7 @@ package com.android.bluetooth.mcp; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.google.common.truth.Truth.assertThat; @@ -47,8 +48,6 @@ import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Captor; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.nio.ByteBuffer; import java.nio.ByteOrder; @@ -62,7 +61,7 @@ import java.util.UUID; @RunWith(AndroidJUnit4.class) public class MediaControlGattServiceTest { @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private AdapterService mAdapterService; @Mock private MediaControlGattService.BluetoothGattServerProxy mGattServer; @@ -1189,6 +1188,76 @@ public class MediaControlGattServiceTest { } @Test + public void testCharacteristic_longReadAuthorized() { + BluetoothGattService service = initAllFeaturesGattService(); + + /* Twenty three octects long title */ + String title = "01234567890123456789012"; + BluetoothGattCharacteristic characteristic = + service.getCharacteristic(MediaControlGattService.UUID_TRACK_TITLE); + characteristic.setValue(title); + + prepareConnectedDevice(); + doReturn(BluetoothDevice.ACCESS_ALLOWED) + .when(mMcpService) + .getDeviceAuthorization(any(BluetoothDevice.class)); + + int offset = 0; + mMediaControlGattService.mServerCallback.onCharacteristicReadRequest( + mCurrentDevice, 1, offset, characteristic); + + verify(mGattServer) + .sendResponse( + eq(mCurrentDevice), + eq(1), + eq(BluetoothGatt.GATT_SUCCESS), + eq(offset), + eq(title.getBytes())); + + offset = characteristic.getValue().length; + mMediaControlGattService.mServerCallback.onCharacteristicReadRequest( + mCurrentDevice, 2, offset, characteristic); + + byte[] empty = new byte[] {}; + verify(mGattServer) + .sendResponse( + eq(mCurrentDevice), + eq(2), + eq(BluetoothGatt.GATT_SUCCESS), + eq(offset), + eq(empty)); + } + + @Test + public void testCharacteristic_longReadOutsideLenAuthorized() { + BluetoothGattService service = initAllFeaturesGattService(); + + /* Twenty three octects long title */ + String title = "01234567890123456789012"; + BluetoothGattCharacteristic characteristic = + service.getCharacteristic(MediaControlGattService.UUID_TRACK_TITLE); + characteristic.setValue(title); + + prepareConnectedDevice(); + doReturn(BluetoothDevice.ACCESS_ALLOWED) + .when(mMcpService) + .getDeviceAuthorization(any(BluetoothDevice.class)); + + int offset = characteristic.getValue().length + 1; + mMediaControlGattService.mServerCallback.onCharacteristicReadRequest( + mCurrentDevice, 1, offset, characteristic); + + byte[] empty = new byte[] {}; + verify(mGattServer) + .sendResponse( + eq(mCurrentDevice), + eq(1), + eq(BluetoothGatt.GATT_INVALID_OFFSET), + eq(offset), + eq(empty)); + } + + @Test public void testCharacteristicNotifyOnAuthorization() { BluetoothGattService service = initAllFeaturesGattService(); prepareConnectedDevice(); diff --git a/android/app/tests/unit/src/com/android/bluetooth/mcp/MediaControlProfileTest.java b/android/app/tests/unit/src/com/android/bluetooth/mcp/MediaControlProfileTest.java index 38c2df6a76..e302f48beb 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/mcp/MediaControlProfileTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/mcp/MediaControlProfileTest.java @@ -16,6 +16,7 @@ package com.android.bluetooth.mcp; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.google.common.truth.Truth.assertThat; @@ -47,8 +48,6 @@ import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Captor; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.util.HashMap; import java.util.UUID; @@ -66,7 +65,7 @@ public class MediaControlProfileTest { private CharSequence charSequence = "TestPlayer"; private MediaControlServiceCallbacks mMcpServiceCallbacks; - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private AdapterService mAdapterService; @Mock private MediaData mMockMediaData; diff --git a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppBtEnablingActivityTest.java b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppBtEnablingActivityTest.java index 804dfdfc64..dafa80f14f 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppBtEnablingActivityTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppBtEnablingActivityTest.java @@ -16,9 +16,10 @@ package com.android.bluetooth.opp; - import static androidx.lifecycle.Lifecycle.State.DESTROYED; +import static com.android.bluetooth.TestUtils.MockitoRule; + import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; @@ -47,14 +48,12 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mockito; import org.mockito.Spy; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.util.concurrent.atomic.AtomicBoolean; @RunWith(AndroidJUnit4.class) public class BluetoothOppBtEnablingActivityTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Spy BluetoothMethodProxy mBluetoothMethodProxy; diff --git a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppHandoverReceiverTest.java b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppHandoverReceiverTest.java index 6bd37adad8..59227bae0b 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppHandoverReceiverTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppHandoverReceiverTest.java @@ -16,6 +16,7 @@ package com.android.bluetooth.opp; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static org.mockito.ArgumentMatchers.eq; @@ -44,8 +45,6 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Spy; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.util.ArrayList; import java.util.List; @@ -55,7 +54,7 @@ import java.util.List; public class BluetoothOppHandoverReceiverTest { Context mContext; - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Spy BluetoothMethodProxy mCallProxy = BluetoothMethodProxy.getInstance(); diff --git a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppLauncherActivityTest.java b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppLauncherActivityTest.java index c162cc9562..6e2b2625b0 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppLauncherActivityTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppLauncherActivityTest.java @@ -16,11 +16,12 @@ package com.android.bluetooth.opp; - import static androidx.test.espresso.intent.Intents.intended; import static androidx.test.espresso.intent.matcher.IntentMatchers.hasAction; import static androidx.test.espresso.intent.matcher.IntentMatchers.hasComponent; +import static com.android.bluetooth.TestUtils.MockitoRule; + import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; @@ -55,8 +56,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.io.File; @@ -67,7 +66,7 @@ public class BluetoothOppLauncherActivityTest { Intent mIntent; BluetoothMethodProxy mMethodProxy; - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock BluetoothOppManager mBluetoothOppManager; diff --git a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppNotificationTest.java b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppNotificationTest.java index 81bf6e5596..7eda9cb7b2 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppNotificationTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppNotificationTest.java @@ -19,6 +19,8 @@ package com.android.bluetooth.opp; import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED; import static android.content.pm.PackageManager.DONT_KILL_APP; +import static com.android.bluetooth.TestUtils.MockitoRule; + import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; @@ -55,15 +57,13 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; @RunWith(AndroidJUnit4.class) public class BluetoothOppNotificationTest { static final int TIMEOUT_MS = 3000; static final int WORKAROUND_TIMEOUT = 3000; - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock BluetoothMethodProxy mMethodProxy; diff --git a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppObexClientSessionTest.java b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppObexClientSessionTest.java index e848b52c8f..51aec2c424 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppObexClientSessionTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppObexClientSessionTest.java @@ -16,6 +16,8 @@ package com.android.bluetooth.opp; +import static com.android.bluetooth.TestUtils.MockitoRule; +import static com.android.bluetooth.TestUtils.mockGetSystemService; import static com.android.bluetooth.opp.BluetoothOppObexSession.MSG_SESSION_COMPLETE; import static com.android.bluetooth.opp.BluetoothOppObexSession.MSG_SHARE_INTERRUPTED; @@ -29,11 +31,13 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.timeout; import static org.mockito.Mockito.verify; +import android.app.NotificationManager; import android.content.Context; import android.net.Uri; import android.os.Handler; import android.os.Looper; import android.os.Message; +import android.os.PowerManager; import androidx.test.platform.app.InstrumentationRegistry; import androidx.test.runner.AndroidJUnit4; @@ -48,8 +52,6 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.io.IOException; import java.io.InputStream; @@ -59,19 +61,24 @@ import java.util.concurrent.TimeUnit; @RunWith(AndroidJUnit4.class) public class BluetoothOppObexClientSessionTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); - @Mock BluetoothMethodProxy mMethodProxy; + @Mock private Context mContext; + @Mock private BluetoothMethodProxy mMethodProxy; + @Mock private BluetoothObexTransport mTransport; - Context mTargetContext; - @Mock BluetoothObexTransport mTransport; + private final Context mTargetContext = + InstrumentationRegistry.getInstrumentation().getTargetContext(); + private final PowerManager mPowerManager = mTargetContext.getSystemService(PowerManager.class); BluetoothOppObexClientSession mClientSession; @Before public void setUp() throws IOException { - mTargetContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); - mClientSession = new BluetoothOppObexClientSession(mTargetContext, mTransport); + mockGetSystemService(mContext, Context.NOTIFICATION_SERVICE, NotificationManager.class); + mockGetSystemService(mContext, Context.POWER_SERVICE, PowerManager.class, mPowerManager); + + mClientSession = new BluetoothOppObexClientSession(mContext, mTransport); // to control the mServerSession.mSession InputStream input = mock(InputStream.class); @@ -190,9 +197,7 @@ public class BluetoothOppObexClientSessionTest { new BluetoothOppSendFileInfo(filename, mimetype, totalBytes, null, status); BluetoothOppObexClientSession.ClientThread thread = - mClientSession - .new ClientThread( - mTargetContext, mTransport, 0, new Handler(Looper.getMainLooper())); + mClientSession.new ClientThread(0, new Handler(Looper.getMainLooper())); InputStream is = mock(InputStream.class); OutputStream os = mock(OutputStream.class); doReturn(is).when(mTransport).openInputStream(); @@ -210,8 +215,6 @@ public class BluetoothOppObexClientSessionTest { BluetoothOppObexClientSession.ClientThread thread = mClientSession .new ClientThread( - mTargetContext, - mTransport, 0, new Handler(Looper.getMainLooper()) { @Override @@ -222,7 +225,9 @@ public class BluetoothOppObexClientSessionTest { } } }); - mClientSession.mWaitingForRemote = true; + synchronized (thread) { + thread.mWaitingForRemote = true; + } thread.interrupt(); assertThat(sessionInterruptLatch.await(3_000, TimeUnit.MILLISECONDS)).isTrue(); } diff --git a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppObexServerSessionTest.java b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppObexServerSessionTest.java index 6b45823e1c..38bcb6a802 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppObexServerSessionTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppObexServerSessionTest.java @@ -16,24 +16,29 @@ package com.android.bluetooth.opp; +import static com.android.bluetooth.TestUtils.MockitoRule; +import static com.android.bluetooth.TestUtils.mockGetSystemService; + import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; +import android.app.NotificationManager; import android.content.Context; -import android.content.ContextWrapper; +import android.content.SharedPreferences; import android.net.Uri; import android.os.Environment; import android.os.Handler; +import android.os.PowerManager; import androidx.test.platform.app.InstrumentationRegistry; import androidx.test.runner.AndroidJUnit4; @@ -51,8 +56,6 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.io.IOException; import java.io.InputStream; @@ -60,26 +63,34 @@ import java.io.OutputStream; @RunWith(AndroidJUnit4.class) public class BluetoothOppObexServerSessionTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock BluetoothMethodProxy mMethodProxy; - - Context mTargetContext; @Mock BluetoothObexTransport mTransport; - @Mock BluetoothOppService mBluetoothOppService; + @Mock NotificationManager mNotificationManager; @Mock Operation mOperation; + @Mock Context mContext; + + private static final String TEST_PREF = "OppObexServer"; - BluetoothOppObexServerSession mServerSession; + private final Context mTargetContext = + InstrumentationRegistry.getInstrumentation().getTargetContext(); + private final PowerManager mPowerManager = mTargetContext.getSystemService(PowerManager.class); + + private BluetoothOppObexServerSession mServerSession; + private SharedPreferences mPrefs; @Before public void setUp() throws IOException { - mTargetContext = - spy( - new ContextWrapper( - InstrumentationRegistry.getInstrumentation().getTargetContext())); - mServerSession = - new BluetoothOppObexServerSession(mTargetContext, mTransport, mBluetoothOppService); + mPrefs = mTargetContext.getSharedPreferences(TEST_PREF, Context.MODE_PRIVATE); + mPrefs.edit().clear().apply(); + + mockGetSystemService(mContext, Context.NOTIFICATION_SERVICE, NotificationManager.class); + mockGetSystemService(mContext, Context.POWER_SERVICE, PowerManager.class, mPowerManager); + + doReturn(mTargetContext.getContentResolver()).when(mContext).getContentResolver(); + doReturn(mPrefs).when(mContext).getSharedPreferences(anyString(), anyInt()); // to control the mServerSession.mSession InputStream input = mock(InputStream.class); @@ -89,23 +100,19 @@ public class BluetoothOppObexServerSessionTest { doReturn(output).when(mTransport).openOutputStream(); BluetoothMethodProxy.setInstanceForTesting(mMethodProxy); + + mServerSession = + new BluetoothOppObexServerSession(mContext, mTransport, mBluetoothOppService); } @After public void tearDown() { + mPrefs.edit().clear().apply(); + mTargetContext.deleteSharedPreferences(TEST_PREF); BluetoothMethodProxy.setInstanceForTesting(null); } @Test - public void constructor_createInstanceCorrectly() { - mServerSession = - new BluetoothOppObexServerSession(mTargetContext, mTransport, mBluetoothOppService); - assertThat(mServerSession.mBluetoothOppService).isEqualTo(mBluetoothOppService); - assertThat(mServerSession.mTransport).isEqualTo(mTransport); - assertThat(mServerSession.mContext).isEqualTo(mTargetContext); - } - - @Test public void unblock() { assertThat(mServerSession.mServerBlocking).isTrue(); mServerSession.unblock(); @@ -327,13 +334,9 @@ public class BluetoothOppObexServerSessionTest { HeaderSet request = new HeaderSet(); HeaderSet reply = new HeaderSet(); request.setHeader(HeaderSet.TARGET, null); - BluetoothOppManager bluetoothOppManager = - spy(BluetoothOppManager.getInstance(mTargetContext)); + BluetoothOppManager bluetoothOppManager = mock(BluetoothOppManager.class); BluetoothOppManager.setInstance(bluetoothOppManager); doReturn(true).when(bluetoothOppManager).isAcceptlisted(any()); - doNothing() - .when(mTargetContext) - .sendBroadcast(any(), eq(Constants.HANDOVER_STATUS_PERMISSION), any()); assertThat(mServerSession.onConnect(request, reply)).isEqualTo(ResponseCodes.OBEX_HTTP_OK); BluetoothOppManager.setInstance(null); diff --git a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppReceiverTest.java b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppReceiverTest.java index ce28a51a69..3dfe6cc5d9 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppReceiverTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppReceiverTest.java @@ -16,6 +16,7 @@ package com.android.bluetooth.opp; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static org.mockito.ArgumentMatchers.any; @@ -53,8 +54,6 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.util.ArrayList; import java.util.List; @@ -64,7 +63,7 @@ public class BluetoothOppReceiverTest { Context mContext; - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock BluetoothMethodProxy mBluetoothMethodProxy; BluetoothOppReceiver mReceiver; diff --git a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppSendFileInfoTest.java b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppSendFileInfoTest.java index aad8a31170..07f3b08c94 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppSendFileInfoTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppSendFileInfoTest.java @@ -18,6 +18,8 @@ package com.android.bluetooth.opp; import static android.os.UserHandle.myUserId; +import static com.android.bluetooth.TestUtils.MockitoRule; + import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; @@ -44,8 +46,6 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.io.FileInputStream; import java.io.IOException; @@ -55,7 +55,7 @@ public class BluetoothOppSendFileInfoTest { Context mContext; MatrixCursor mCursor; - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock BluetoothMethodProxy mCallProxy; diff --git a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppServiceCleanupTest.java b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppServiceCleanupTest.java index 935c1bf471..e84d87bbfc 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppServiceCleanupTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppServiceCleanupTest.java @@ -19,6 +19,8 @@ package com.android.bluetooth.opp; import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED; import static android.content.pm.PackageManager.DONT_KILL_APP; +import static com.android.bluetooth.TestUtils.MockitoRule; + import android.content.ComponentName; import android.content.ContentValues; import android.content.Context; @@ -33,13 +35,11 @@ import com.android.bluetooth.btservice.AdapterService; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; @SmallTest @RunWith(AndroidJUnit4.class) public class BluetoothOppServiceCleanupTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); private final Context mTargetContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); diff --git a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppServiceTest.java index dd14319b17..0d5b6c61ba 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppServiceTest.java @@ -15,6 +15,7 @@ */ package com.android.bluetooth.opp; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.opp.BluetoothOppService.WHERE_INVISIBLE_UNCONFIRMED; import static com.google.common.truth.Truth.assertThat; @@ -48,13 +49,11 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.Mockito; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; @MediumTest @RunWith(AndroidJUnit4.class) public class BluetoothOppServiceTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private BluetoothMethodProxy mBluetoothMethodProxy; diff --git a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppTransferActivityTest.java b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppTransferActivityTest.java index 2eaa49cf18..5a268d1614 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppTransferActivityTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppTransferActivityTest.java @@ -16,6 +16,7 @@ package com.android.bluetooth.opp; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.opp.BluetoothOppTestUtils.CursorMockData; import static com.android.bluetooth.opp.BluetoothOppTransferActivity.DIALOG_RECEIVE_COMPLETE_FAIL; import static com.android.bluetooth.opp.BluetoothOppTransferActivity.DIALOG_RECEIVE_COMPLETE_SUCCESS; @@ -50,8 +51,6 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.Spy; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.util.ArrayList; import java.util.List; @@ -59,7 +58,7 @@ import java.util.concurrent.atomic.AtomicBoolean; @RunWith(AndroidJUnit4.class) public class BluetoothOppTransferActivityTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock Cursor mCursor; @Spy BluetoothMethodProxy mBluetoothMethodProxy; diff --git a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppTransferHistoryTest.java b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppTransferHistoryTest.java index 69d01b2853..3d313bdfb5 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppTransferHistoryTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppTransferHistoryTest.java @@ -23,6 +23,8 @@ import static androidx.test.espresso.matcher.RootMatchers.isDialog; import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; import static androidx.test.espresso.matcher.ViewMatchers.withText; +import static com.android.bluetooth.TestUtils.MockitoRule; + import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.Mockito.any; import static org.mockito.Mockito.doReturn; @@ -57,8 +59,6 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.Spy; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.util.ArrayList; import java.util.List; @@ -66,7 +66,7 @@ import java.util.List; /** This class will also test BluetoothOppTransferAdapter */ @RunWith(AndroidJUnit4.class) public class BluetoothOppTransferHistoryTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock Cursor mCursor; @Spy BluetoothMethodProxy mBluetoothMethodProxy; diff --git a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppTransferTest.java b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppTransferTest.java index aecf7856ef..3433c9e323 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppTransferTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppTransferTest.java @@ -15,6 +15,7 @@ */ package com.android.bluetooth.opp; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.android.bluetooth.opp.BluetoothOppTransfer.TRANSPORT_CONNECTED; import static com.android.bluetooth.opp.BluetoothOppTransfer.TRANSPORT_ERROR; @@ -59,15 +60,13 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.util.Objects; @MediumTest @RunWith(AndroidJUnit4.class) public class BluetoothOppTransferTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Rule public final SetFlagsRule mSetFlagRule = new SetFlagsRule(); @Mock BluetoothOppObexSession mSession; diff --git a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppUtilityTest.java b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppUtilityTest.java index 1308e36fc2..4607569b83 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppUtilityTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppUtilityTest.java @@ -16,6 +16,8 @@ package com.android.bluetooth.opp; +import static com.android.bluetooth.TestUtils.MockitoRule; + import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; @@ -56,8 +58,6 @@ import org.junit.Rule; import org.junit.Test; import org.mockito.Mock; import org.mockito.Spy; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.util.List; import java.util.Objects; @@ -70,7 +70,7 @@ public class BluetoothOppUtilityTest { private static final Uri INCORRECT_FORMAT_URI = Uri.parse("www.google.com"); Context mContext; - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock Cursor mCursor; diff --git a/android/app/tests/unit/src/com/android/bluetooth/opp/IncomingFileConfirmActivityTest.java b/android/app/tests/unit/src/com/android/bluetooth/opp/IncomingFileConfirmActivityTest.java index b43c6f93a6..8a5a10e271 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/opp/IncomingFileConfirmActivityTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/opp/IncomingFileConfirmActivityTest.java @@ -23,6 +23,7 @@ import static androidx.test.espresso.matcher.RootMatchers.isDialog; import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; import static androidx.test.espresso.matcher.ViewMatchers.withText; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.opp.BluetoothOppIncomingFileConfirmActivity.DISMISS_TIMEOUT_DIALOG; import static com.android.bluetooth.opp.BluetoothOppIncomingFileConfirmActivity.DISMISS_TIMEOUT_DIALOG_VALUE; @@ -62,8 +63,6 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.Spy; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.util.ArrayList; import java.util.List; @@ -72,7 +71,7 @@ import java.util.concurrent.atomic.AtomicBoolean; // Long class name cause problem with Junit4. It will raise java.lang.NoClassDefFoundError @RunWith(AndroidJUnit4.class) public class IncomingFileConfirmActivityTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock Cursor mCursor; @Spy BluetoothMethodProxy mBluetoothMethodProxy; diff --git a/android/app/tests/unit/src/com/android/bluetooth/pan/BluetoothTetheringNetworkFactoryTest.java b/android/app/tests/unit/src/com/android/bluetooth/pan/BluetoothTetheringNetworkFactoryTest.java index 4fa6eb35f5..d148cde55d 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/pan/BluetoothTetheringNetworkFactoryTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/pan/BluetoothTetheringNetworkFactoryTest.java @@ -16,6 +16,7 @@ package com.android.bluetooth.pan; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.google.common.truth.Truth.assertThat; @@ -35,8 +36,6 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.util.ArrayList; import java.util.List; @@ -46,7 +45,7 @@ import java.util.List; @RunWith(AndroidJUnit4.class) public class BluetoothTetheringNetworkFactoryTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private PanService mPanService; diff --git a/android/app/tests/unit/src/com/android/bluetooth/pan/PanServiceBinderTest.java b/android/app/tests/unit/src/com/android/bluetooth/pan/PanServiceBinderTest.java index f1c0704f5c..2975803aaf 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/pan/PanServiceBinderTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/pan/PanServiceBinderTest.java @@ -16,6 +16,7 @@ package com.android.bluetooth.pan; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static org.mockito.Mockito.verify; @@ -31,13 +32,11 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; @SmallTest @RunWith(AndroidJUnit4.class) public class PanServiceBinderTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private PanService mService; diff --git a/android/app/tests/unit/src/com/android/bluetooth/pan/PanServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/pan/PanServiceTest.java index b54e55031e..eb0602a9b6 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/pan/PanServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/pan/PanServiceTest.java @@ -19,6 +19,7 @@ import static android.bluetooth.BluetoothPan.PAN_ROLE_NONE; import static android.net.TetheringManager.TETHERING_BLUETOOTH; import static android.net.TetheringManager.TETHER_ERROR_SERVICE_UNAVAIL; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.google.common.truth.Truth.assertThat; @@ -51,13 +52,11 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; @MediumTest @RunWith(AndroidJUnit4.class) public class PanServiceTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private AdapterService mAdapterService; @Mock private DatabaseManager mDatabaseManager; diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapAuthenticatorTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapAuthenticatorTest.java index 60b79dce88..78d61ff046 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapAuthenticatorTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapAuthenticatorTest.java @@ -16,6 +16,8 @@ package com.android.bluetooth.pbap; +import static com.android.bluetooth.TestUtils.MockitoRule; + import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.doAnswer; @@ -31,8 +33,6 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; @MediumTest @RunWith(AndroidJUnit4.class) @@ -40,7 +40,7 @@ public class BluetoothPbapAuthenticatorTest { private BluetoothPbapAuthenticator mAuthenticator; - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock PbapStateMachine mMockPbapStateMachine; diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapCallLogComposerTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapCallLogComposerTest.java index 98c45fa5c3..c781ca82ac 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapCallLogComposerTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapCallLogComposerTest.java @@ -16,6 +16,7 @@ package com.android.bluetooth.pbap; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.pbap.BluetoothPbapCallLogComposer.FAILURE_REASON_FAILED_TO_GET_DATABASE_INFO; import static com.android.bluetooth.pbap.BluetoothPbapCallLogComposer.FAILURE_REASON_NOT_INITIALIZED; import static com.android.bluetooth.pbap.BluetoothPbapCallLogComposer.FAILURE_REASON_NO_ENTRY; @@ -47,8 +48,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.Spy; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; @SmallTest @RunWith(AndroidJUnit4.class) @@ -66,7 +65,7 @@ public class BluetoothPbapCallLogComposerTest { @Spy BluetoothMethodProxy mPbapCallProxy = BluetoothMethodProxy.getInstance(); - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock Cursor mMockCursor; diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapConfigTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapConfigTest.java index 634fe3b247..f57cbc2758 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapConfigTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapConfigTest.java @@ -16,6 +16,8 @@ package com.android.bluetooth.pbap; +import static com.android.bluetooth.TestUtils.MockitoRule; + import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.when; @@ -33,14 +35,12 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; @SmallTest @RunWith(AndroidJUnit4.class) public class BluetoothPbapConfigTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock Context mContext; diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapObexServerTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapObexServerTest.java index c281b95d18..48ffaaad29 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapObexServerTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapObexServerTest.java @@ -16,6 +16,7 @@ package com.android.bluetooth.pbap; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.obex.ApplicationParameter.TRIPLET_LENGTH.FORMAT_LENGTH; import static com.android.obex.ApplicationParameter.TRIPLET_LENGTH.LISTSTARTOFFSET_LENGTH; import static com.android.obex.ApplicationParameter.TRIPLET_LENGTH.ORDER_LENGTH; @@ -72,8 +73,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.Spy; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.io.IOException; import java.io.OutputStream; @@ -84,7 +83,7 @@ public class BluetoothPbapObexServerTest { private static final String TAG = BluetoothPbapObexServerTest.class.getSimpleName(); - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock Handler mMockHandler; @Mock PbapStateMachine mMockStateMachine; diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapServiceBinderTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapServiceBinderTest.java index c8d9941ed2..ec398bd913 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapServiceBinderTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapServiceBinderTest.java @@ -16,6 +16,7 @@ package com.android.bluetooth.pbap; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static org.mockito.Mockito.verify; @@ -31,13 +32,11 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; @MediumTest @RunWith(AndroidJUnit4.class) public class BluetoothPbapServiceBinderTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private BluetoothPbapService mService; diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapServiceTest.java index 61bd699dd8..44169c9c28 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapServiceTest.java @@ -15,6 +15,7 @@ */ package com.android.bluetooth.pbap; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.google.common.truth.Truth.assertThat; @@ -57,8 +58,6 @@ import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.Spy; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.util.List; @@ -66,7 +65,7 @@ import java.util.List; @RunWith(AndroidJUnit4.class) public class BluetoothPbapServiceTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private AdapterService mAdapterService; @Mock private DatabaseManager mDatabaseManager; @@ -99,7 +98,6 @@ public class BluetoothPbapServiceTest { mTestLooper.startAutoDispatch(); doReturn(mDatabaseManager).when(mAdapterService).getDatabase(); mService = new BluetoothPbapService(mAdapterService, mNotificationManager); - mService.start(); mService.setAvailable(true); PackageManager pm = mTargetContext.getPackageManager(); diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapSimVcardManagerTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapSimVcardManagerTest.java index c90655949a..2142da1431 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapSimVcardManagerTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapSimVcardManagerTest.java @@ -16,6 +16,8 @@ package com.android.bluetooth.pbap; +import static com.android.bluetooth.TestUtils.MockitoRule; + import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; @@ -45,8 +47,6 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Spy; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import org.mockito.stubbing.Answer; import java.io.OutputStream; @@ -62,7 +62,7 @@ public class BluetoothPbapSimVcardManagerTest { private static final String TAG = BluetoothPbapSimVcardManagerTest.class.getSimpleName(); - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Spy BluetoothMethodProxy mPbapMethodProxy = BluetoothMethodProxy.getInstance(); diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapUtilsTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapUtilsTest.java index bfae8a9165..2f4760f451 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapUtilsTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapUtilsTest.java @@ -20,6 +20,8 @@ import static android.provider.ContactsContract.Data.CONTACT_ID; import static android.provider.ContactsContract.Data.DATA1; import static android.provider.ContactsContract.Data.MIMETYPE; +import static com.android.bluetooth.TestUtils.MockitoRule; + import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; @@ -53,8 +55,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.Spy; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.util.ArrayList; import java.util.Calendar; @@ -64,7 +64,7 @@ import java.util.List; @RunWith(AndroidJUnit4.class) public class BluetoothPbapUtilsTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock Context mContext; diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapVcardManagerNestedClassesTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapVcardManagerNestedClassesTest.java index 424ad9ebc5..1302bb4c08 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapVcardManagerNestedClassesTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapVcardManagerNestedClassesTest.java @@ -16,6 +16,8 @@ package com.android.bluetooth.pbap; +import static com.android.bluetooth.TestUtils.MockitoRule; + import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.mock; @@ -38,8 +40,6 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.util.concurrent.atomic.AtomicInteger; @@ -47,7 +47,7 @@ import java.util.concurrent.atomic.AtomicInteger; @RunWith(AndroidJUnit4.class) public class BluetoothPbapVcardManagerNestedClassesTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock Context mContext; diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapVcardManagerTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapVcardManagerTest.java index ea0734a75c..e4defeeff8 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapVcardManagerTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapVcardManagerTest.java @@ -16,6 +16,8 @@ package com.android.bluetooth.pbap; +import static com.android.bluetooth.TestUtils.MockitoRule; + import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.anyInt; @@ -43,8 +45,6 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Spy; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import org.mockito.stubbing.Answer; import java.util.Arrays; @@ -57,7 +57,7 @@ public class BluetoothPbapVcardManagerTest { private static final String TAG = BluetoothPbapVcardManagerTest.class.getSimpleName(); - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Spy BluetoothMethodProxy mPbapMethodProxy = BluetoothMethodProxy.getInstance(); diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbap/HandlerForStringBufferTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbap/HandlerForStringBufferTest.java index 9c9ee8967f..7245788429 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/pbap/HandlerForStringBufferTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/pbap/HandlerForStringBufferTest.java @@ -16,6 +16,8 @@ package com.android.bluetooth.pbap; +import static com.android.bluetooth.TestUtils.MockitoRule; + import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.any; @@ -34,8 +36,6 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.io.IOException; import java.io.OutputStream; @@ -44,7 +44,7 @@ import java.io.OutputStream; @RunWith(AndroidJUnit4.class) public class HandlerForStringBufferTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private Operation mOperation; diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbap/PbapStateMachineTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbap/PbapStateMachineTest.java index 647f2ff973..e33e2a30bf 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/pbap/PbapStateMachineTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/pbap/PbapStateMachineTest.java @@ -16,6 +16,7 @@ package com.android.bluetooth.pbap; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.google.common.truth.Truth.assertThat; @@ -38,13 +39,11 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; @MediumTest @RunWith(AndroidJUnit4.class) public class PbapStateMachineTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private BluetoothPbapService mBluetoothPbapService; diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/CallLogPullRequestTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/CallLogPullRequestTest.java index 43d12765c2..fdadac66b8 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/CallLogPullRequestTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/CallLogPullRequestTest.java @@ -16,6 +16,8 @@ package com.android.bluetooth.pbapclient; +import static com.android.bluetooth.TestUtils.MockitoRule; + import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.doReturn; @@ -40,8 +42,6 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.util.ArrayList; import java.util.HashMap; @@ -51,7 +51,7 @@ import java.util.List; @RunWith(AndroidJUnit4.class) public class CallLogPullRequestTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); private final Account mAccount = mock(Account.class); private final HashMap<String, Integer> mCallCounter = new HashMap<>(); diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientAccountManagerTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientAccountManagerTest.java index 8279e2ed1b..5126cd500e 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientAccountManagerTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientAccountManagerTest.java @@ -16,6 +16,7 @@ package com.android.bluetooth.pbapclient; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.google.common.truth.Truth.assertThat; @@ -57,8 +58,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.util.List; @@ -66,7 +65,7 @@ import java.util.List; public class PbapClientAccountManagerTest { private static final String ACCOUNT_TYPE = "com.android.bluetooth.pbapclient.account"; - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); private BluetoothAdapter mAdapter; diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientBinderTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientBinderTest.java index 6d0d407577..21f4d58849 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientBinderTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientBinderTest.java @@ -16,6 +16,7 @@ package com.android.bluetooth.pbapclient; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.google.common.truth.Truth.assertThat; @@ -39,15 +40,13 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.util.List; @MediumTest @RunWith(AndroidJUnit4.class) public class PbapClientBinderTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private PbapClientService mMockService; private BluetoothDevice mTestDevice; diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientConnectionHandlerTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientConnectionHandlerTest.java index 454d9cb976..2d90f7e178 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientConnectionHandlerTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientConnectionHandlerTest.java @@ -16,6 +16,7 @@ package com.android.bluetooth.pbapclient; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.google.common.truth.Truth.assertThat; @@ -43,13 +44,11 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; @SmallTest @RunWith(AndroidJUnit4.class) public class PbapClientConnectionHandlerTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private PbapClientService mService; @Mock private Resources mMockResources; diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientContactsStorageTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientContactsStorageTest.java index d00b08a62a..168f9b782c 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientContactsStorageTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientContactsStorageTest.java @@ -16,6 +16,7 @@ package com.android.bluetooth.pbapclient; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.google.common.truth.Truth.assertThat; @@ -56,8 +57,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.io.File; import java.time.Instant; @@ -71,7 +70,7 @@ import java.util.List; @MediumTest @RunWith(AndroidJUnit4.class) public class PbapClientContactsStorageTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); private static final String ACCOUNT_TYPE = "com.android.bluetooth.pbapclient.account"; diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientObexClientTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientObexClientTest.java index ccf3556af5..0db11cbb38 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientObexClientTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientObexClientTest.java @@ -16,6 +16,7 @@ package com.android.bluetooth.pbapclient; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.google.common.truth.Truth.assertThat; @@ -54,8 +55,6 @@ import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Captor; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.io.IOException; import java.util.ArrayList; @@ -69,7 +68,7 @@ public class PbapClientObexClientTest { private static final int TEST_L2CAP_PSM = 4098; private static final int TEST_RFCOMM_CHANNEL_ID = 3; - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); private BluetoothAdapter mAdapter = null; private BluetoothDevice mDevice; diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientObexTransportTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientObexTransportTest.java index abc05cc314..29fc05c955 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientObexTransportTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientObexTransportTest.java @@ -16,6 +16,7 @@ package com.android.bluetooth.pbapclient; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.google.common.truth.Truth.assertThat; @@ -34,8 +35,6 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.io.DataInputStream; import java.io.DataOutputStream; @@ -45,7 +44,7 @@ import java.io.OutputStream; @RunWith(AndroidJUnit4.class) public class PbapClientObexTransportTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); private BluetoothDevice mTestDevice; diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientServiceTest.java index c62eacf944..f4366b38f3 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientServiceTest.java @@ -23,6 +23,7 @@ import static android.bluetooth.BluetoothProfile.STATE_CONNECTING; import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTED; import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTING; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.google.common.truth.Truth.assertThat; @@ -73,8 +74,6 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import platform.test.runner.parameterized.ParameterizedAndroidJunit4; import platform.test.runner.parameterized.Parameters; @@ -89,7 +88,7 @@ import java.util.Map; @RunWith(ParameterizedAndroidJunit4.class) public class PbapClientServiceTest { @Rule public final SetFlagsRule mSetFlagsRule; - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private AdapterService mAdapterService; @Mock private DatabaseManager mDatabaseManager; diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientSocketTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientSocketTest.java index de80730ae6..a3380b177b 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientSocketTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientSocketTest.java @@ -16,6 +16,7 @@ package com.android.bluetooth.pbapclient; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.google.common.truth.Truth.assertThat; @@ -32,8 +33,6 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.io.IOException; import java.io.InputStream; @@ -41,7 +40,7 @@ import java.io.OutputStream; @RunWith(AndroidJUnit4.class) public class PbapClientSocketTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); private static final int TEST_L2CAP_PSM = 4098; private static final int TEST_RFCOMM_CHANNEL_ID = 3; diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientStateMachineOldTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientStateMachineOldTest.java index bfc4342dc6..38fdc4f370 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientStateMachineOldTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientStateMachineOldTest.java @@ -15,14 +15,15 @@ */ package com.android.bluetooth.pbapclient; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; +import static com.android.bluetooth.TestUtils.mockGetSystemService; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.any; import static org.mockito.Mockito.timeout; import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; import android.app.BroadcastOptions; import android.bluetooth.BluetoothDevice; @@ -45,16 +46,13 @@ import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.Mockito; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; @MediumTest @RunWith(AndroidJUnit4.class) public class PbapClientStateMachineOldTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private PbapClientService mMockPbapClientService; - @Mock private UserManager mMockUserManager; @Mock private PbapClientConnectionHandler mMockHandler; private static final String TAG = "PbapClientStateMachineOldTest"; @@ -67,10 +65,8 @@ public class PbapClientStateMachineOldTest { @Before public void setUp() throws Exception { - when(mMockPbapClientService.getSystemServiceName(UserManager.class)) - .thenReturn(Context.USER_SERVICE); - when(mMockPbapClientService.getSystemService(UserManager.class)) - .thenReturn(mMockUserManager); + mockGetSystemService(mMockPbapClientService, Context.USER_SERVICE, UserManager.class); + mPbapClientStateMachine = new PbapClientStateMachineOld(mMockPbapClientService, mDevice, mMockHandler); mPbapClientStateMachine.start(); diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientStateMachineTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientStateMachineTest.java index a2ec6815e0..d8dc5d4e4b 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientStateMachineTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientStateMachineTest.java @@ -16,6 +16,7 @@ package com.android.bluetooth.pbapclient; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.google.common.truth.Truth.assertThat; @@ -54,8 +55,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.util.ArrayList; import java.util.List; @@ -83,7 +82,7 @@ public class PbapClientStateMachineTest { private static final int SDP_BUSY = 2; private static final int SDP_UNKNOWN = -1; - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); private BluetoothDevice mTestDevice; diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapPhonebookTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapPhonebookTest.java index 9b77b17de8..214a08bf27 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapPhonebookTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapPhonebookTest.java @@ -16,6 +16,8 @@ package com.android.bluetooth.pbapclient; +import static com.android.bluetooth.TestUtils.MockitoRule; + import static com.google.common.truth.Truth.assertThat; import androidx.test.runner.AndroidJUnit4; @@ -23,9 +25,6 @@ import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.io.ByteArrayInputStream; import java.io.IOException; @@ -36,7 +35,7 @@ import java.util.Arrays; @RunWith(AndroidJUnit4.class) public class PbapPhonebookTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); // ********************************************************************************************* // * Create Phonebook diff --git a/android/app/tests/unit/src/com/android/bluetooth/sap/SapRilReceiverHidlTest.java b/android/app/tests/unit/src/com/android/bluetooth/sap/SapRilReceiverHidlTest.java index 094b9d67ec..c87956cfb4 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/sap/SapRilReceiverHidlTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/sap/SapRilReceiverHidlTest.java @@ -16,6 +16,7 @@ package com.android.bluetooth.sap; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.sap.SapMessage.CON_STATUS_OK; import static com.android.bluetooth.sap.SapMessage.DISC_GRACEFULL; import static com.android.bluetooth.sap.SapMessage.ID_CONNECT_RESP; @@ -66,8 +67,6 @@ import org.junit.runner.RunWith; import org.mockito.ArgumentMatcher; import org.mockito.Mock; import org.mockito.Spy; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.util.ArrayList; import java.util.Arrays; @@ -83,7 +82,7 @@ public class SapRilReceiverHidlTest { @Spy private TestHandlerCallback mCallback = new TestHandlerCallback(); - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private Handler mServiceHandler; diff --git a/android/app/tests/unit/src/com/android/bluetooth/sap/SapRilReceiverTest.java b/android/app/tests/unit/src/com/android/bluetooth/sap/SapRilReceiverTest.java index 50199e4fd3..9df3905124 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/sap/SapRilReceiverTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/sap/SapRilReceiverTest.java @@ -16,6 +16,7 @@ package com.android.bluetooth.sap; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.sap.SapMessage.CON_STATUS_OK; import static com.android.bluetooth.sap.SapMessage.DISC_GRACEFULL; import static com.android.bluetooth.sap.SapMessage.ID_CONNECT_RESP; @@ -69,8 +70,6 @@ import org.junit.runner.RunWith; import org.mockito.ArgumentMatcher; import org.mockito.Mock; import org.mockito.Spy; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.util.Arrays; @@ -85,7 +84,7 @@ public class SapRilReceiverTest { @Spy private TestHandlerCallback mCallback = new TestHandlerCallback(); - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private Handler mServiceHandler; diff --git a/android/app/tests/unit/src/com/android/bluetooth/sap/SapServerTest.java b/android/app/tests/unit/src/com/android/bluetooth/sap/SapServerTest.java index 740d9c8e27..48f6a4de6d 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/sap/SapServerTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/sap/SapServerTest.java @@ -16,6 +16,7 @@ package com.android.bluetooth.sap; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.sap.SapMessage.CON_STATUS_ERROR_CONNECTION; import static com.android.bluetooth.sap.SapMessage.CON_STATUS_OK; import static com.android.bluetooth.sap.SapMessage.CON_STATUS_OK_ONGOING_CALL; @@ -78,8 +79,6 @@ import org.mockito.ArgumentCaptor; import org.mockito.ArgumentMatcher; import org.mockito.Mock; import org.mockito.Spy; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.io.InputStream; import java.io.OutputStream; @@ -98,7 +97,7 @@ public class SapServerTest { @Spy private TestHandlerCallback mCallback = new TestHandlerCallback(); - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private InputStream mInputStream; diff --git a/android/app/tests/unit/src/com/android/bluetooth/sap/SapServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/sap/SapServiceTest.java index ace1a46b84..93961ed478 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/sap/SapServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/sap/SapServiceTest.java @@ -16,6 +16,7 @@ package com.android.bluetooth.sap; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.google.common.truth.Truth.assertThat; @@ -40,13 +41,11 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; @MediumTest @RunWith(AndroidJUnit4.class) public class SapServiceTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private AdapterService mAdapterService; @Mock private DatabaseManager mDatabaseManager; diff --git a/android/app/tests/unit/src/com/android/bluetooth/sdp/DipTest.java b/android/app/tests/unit/src/com/android/bluetooth/sdp/DipTest.java index c60c3b8242..ce797f2d30 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/sdp/DipTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/sdp/DipTest.java @@ -16,6 +16,7 @@ package com.android.bluetooth.sdp; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.google.common.truth.Truth.assertThat; @@ -45,13 +46,11 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; @SmallTest @RunWith(AndroidJUnit4.class) public class DipTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private AdapterService mAdapterService; @Mock private SdpManagerNativeInterface mNativeInterface; diff --git a/android/app/tests/unit/src/com/android/bluetooth/tbs/TbsGattTest.java b/android/app/tests/unit/src/com/android/bluetooth/tbs/TbsGattTest.java index 0678f0716e..df7ed3946f 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/tbs/TbsGattTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/tbs/TbsGattTest.java @@ -17,6 +17,7 @@ package com.android.bluetooth.tbs; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.google.common.truth.Truth.assertThat; @@ -46,8 +47,6 @@ import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Captor; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.nio.charset.StandardCharsets; import java.util.ArrayList; @@ -60,7 +59,7 @@ import java.util.UUID; @MediumTest @RunWith(AndroidJUnit4.class) public class TbsGattTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Rule public final ServiceTestRule mServiceRule = new ServiceTestRule(); @Mock private AdapterService mAdapterService; diff --git a/android/app/tests/unit/src/com/android/bluetooth/tbs/TbsGenericTest.java b/android/app/tests/unit/src/com/android/bluetooth/tbs/TbsGenericTest.java index 462ec3c4c5..8000d9191b 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/tbs/TbsGenericTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/tbs/TbsGenericTest.java @@ -16,6 +16,7 @@ package com.android.bluetooth.tbs; import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.google.common.truth.Truth.assertThat; @@ -41,8 +42,6 @@ import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Captor; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.util.ArrayList; import java.util.Arrays; @@ -54,7 +53,7 @@ import java.util.UUID; @MediumTest @RunWith(AndroidJUnit4.class) public class TbsGenericTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private TbsGatt mTbsGatt; @Mock private IBluetoothLeCallControlCallback mIBluetoothLeCallControlCallback; @Captor private ArgumentCaptor<Integer> mGtbsCcidCaptor; diff --git a/android/app/tests/unit/src/com/android/bluetooth/telephony/BluetoothInCallServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/telephony/BluetoothInCallServiceTest.java index b26a66e7a1..593a09ebbb 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/telephony/BluetoothInCallServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/telephony/BluetoothInCallServiceTest.java @@ -16,6 +16,8 @@ package com.android.bluetooth.telephony; +import static com.android.bluetooth.TestUtils.MockitoRule; + import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; @@ -58,8 +60,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.util.ArrayList; import java.util.Arrays; @@ -95,7 +95,7 @@ public class BluetoothInCallServiceTest { private BluetoothInCallService mBluetoothInCallService; - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); @Mock private BluetoothHeadsetProxy mMockBluetoothHeadset; diff --git a/android/app/tests/unit/src/com/android/bluetooth/telephony/CallInfoTest.java b/android/app/tests/unit/src/com/android/bluetooth/telephony/CallInfoTest.java index b792dbe2ca..a87d95f349 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/telephony/CallInfoTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/telephony/CallInfoTest.java @@ -16,6 +16,8 @@ package com.android.bluetooth.telephony; +import static com.android.bluetooth.TestUtils.MockitoRule; + import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.doReturn; @@ -44,8 +46,6 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.util.ArrayList; import java.util.LinkedHashSet; @@ -59,7 +59,7 @@ public class CallInfoTest { private static final String TEST_ACCOUNT_ADDRESS = "https://foo.com/"; private static final int TEST_ACCOUNT_INDEX = 0; - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); private TelecomManager mMockTelecomManager; diff --git a/android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlInputDescriptorTest.java b/android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlInputDescriptorTest.java index 07c599531c..eac31c5d95 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlInputDescriptorTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlInputDescriptorTest.java @@ -15,6 +15,7 @@ */ package com.android.bluetooth.vc; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.google.common.truth.Truth.assertThat; @@ -36,13 +37,11 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; @SmallTest @RunWith(AndroidJUnit4.class) public class VolumeControlInputDescriptorTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); @Mock private VolumeControlNativeInterface mNativeInterface; diff --git a/android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlNativeCallbackTest.java b/android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlNativeCallbackTest.java index 20e3fcd088..7a727f5d7f 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlNativeCallbackTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlNativeCallbackTest.java @@ -16,6 +16,7 @@ package com.android.bluetooth.vc; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.vc.VolumeControlStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED; import static com.android.bluetooth.vc.VolumeControlStackEvent.EVENT_TYPE_DEVICE_AVAILABLE; import static com.android.bluetooth.vc.VolumeControlStackEvent.EVENT_TYPE_EXT_AUDIO_OUT_DESCRIPTION_CHANGED; @@ -43,12 +44,10 @@ import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Captor; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; @RunWith(AndroidJUnit4.class) public class VolumeControlNativeCallbackTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Rule public Expect expect = Expect.create(); @Mock private AdapterService mAdapterService; diff --git a/android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlServiceTest.java index e9e5f1028b..d4143821b8 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlServiceTest.java @@ -34,6 +34,7 @@ import static android.bluetooth.IBluetoothVolumeControl.VOLUME_CONTROL_UNKNOWN_V import static androidx.test.espresso.intent.matcher.IntentMatchers.hasAction; import static androidx.test.espresso.intent.matcher.IntentMatchers.hasExtra; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.google.common.truth.Truth.assertThat; @@ -89,8 +90,6 @@ import org.mockito.InOrder; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.hamcrest.MockitoHamcrest; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; import java.util.ArrayList; import java.util.Arrays; @@ -100,7 +99,7 @@ import java.util.stream.IntStream; @MediumTest @RunWith(AndroidJUnit4.class) public class VolumeControlServiceTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); @Mock private AdapterService mAdapterService; diff --git a/android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlStateMachineTest.java b/android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlStateMachineTest.java index 2b4d92ef47..40b274f7e6 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlStateMachineTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlStateMachineTest.java @@ -28,6 +28,7 @@ import static android.bluetooth.BluetoothVolumeControl.ACTION_CONNECTION_STATE_C import static androidx.test.espresso.intent.matcher.IntentMatchers.hasAction; import static androidx.test.espresso.intent.matcher.IntentMatchers.hasExtra; +import static com.android.bluetooth.TestUtils.MockitoRule; import static com.android.bluetooth.TestUtils.getTestDevice; import static com.android.bluetooth.vc.VolumeControlStateMachine.MESSAGE_CONNECT; import static com.android.bluetooth.vc.VolumeControlStateMachine.MESSAGE_CONNECT_TIMEOUT; @@ -61,13 +62,11 @@ import org.junit.runner.RunWith; import org.mockito.InOrder; import org.mockito.Mock; import org.mockito.hamcrest.MockitoHamcrest; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; @MediumTest @RunWith(AndroidJUnit4.class) public class VolumeControlStateMachineTest { - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = new MockitoRule(); @Mock private VolumeControlService mService; @Mock private VolumeControlNativeInterface mNativeInterface; diff --git a/android/pandora/server/configs/PtsBotTestMts.xml b/android/pandora/server/configs/PtsBotTestMts.xml index 00fb46bfbd..4d3605549c 100644 --- a/android/pandora/server/configs/PtsBotTestMts.xml +++ b/android/pandora/server/configs/PtsBotTestMts.xml @@ -53,6 +53,7 @@ <option name="profile" value="BNEP" /> <option name="profile" value="GAP" /> <option name="profile" value="GATT" /> + <option name="profile" value="HAP" /> <option name="profile" value="HFP/AG" /> <option name="profile" value="HFP/HF" /> <option name="profile" value="HID/HOS" /> @@ -69,6 +70,7 @@ <option name="profile" value="RFCOMM" /> <option name="profile" value="SDP" /> <option name="profile" value="SM" /> + <option name="profile" value="VCP" /> </test> <object type="module_controller" diff --git a/flags/a2dp.aconfig b/flags/a2dp.aconfig index 465054f1b8..36b7b7ddc5 100644 --- a/flags/a2dp.aconfig +++ b/flags/a2dp.aconfig @@ -22,16 +22,6 @@ flag { } flag { - name: "avrcp_sdp_records" - namespace: "bluetooth" - description: "Update SDP records for AVRC" - bug: "341353017" - metadata { - purpose: PURPOSE_BUGFIX - } -} - -flag { name: "a2dp_variable_aac_capability" namespace: "bluetooth" description: "Enable AAC 48 kHz sampling rate for sink devices in the allow list" diff --git a/flags/connectivity.aconfig b/flags/connectivity.aconfig index c8dca9cb5f..482c7e68e8 100644 --- a/flags/connectivity.aconfig +++ b/flags/connectivity.aconfig @@ -26,16 +26,6 @@ flag { } flag { - name: "progress_acl_scheduler_upon_incoming_connection" - namespace: "bluetooth" - description: "Allow outgoing connections to other devices and rnr to same device" - bug: "355256744" - metadata { - purpose: PURPOSE_BUGFIX - } -} - -flag { name: "allow_gatt_connect_from_the_apps_without_making_leaudio_device_active" namespace: "bluetooth" description: "Allows for GATT connection without making LeAudio device active after connection" diff --git a/flags/framework.aconfig b/flags/framework.aconfig index df4cf067f5..9e38015d0b 100644 --- a/flags/framework.aconfig +++ b/flags/framework.aconfig @@ -10,14 +10,6 @@ flag { } flag { - name: "support_exclusive_manager" - is_exported: true - namespace: "bluetooth" - description: "Support setting/retrieving the exclusive manager app for a BluetoothDevice" - bug: "319716512" -} - -flag { name: "identity_address_null_if_not_known" namespace: "bluetooth" description: "Return null for identity address if identity address is not known" diff --git a/flags/gap.aconfig b/flags/gap.aconfig index 5da5144aa1..d9d5c6905d 100644 --- a/flags/gap.aconfig +++ b/flags/gap.aconfig @@ -9,13 +9,6 @@ flag { } flag { - name: "fix_nonconnectable_scannable_advertisement" - namespace: "bluetooth" - description: "Fix adv_scan_ind being reported as connectable" - bug: "316013235" -} - -flag { name: "scan_manager_refactor" namespace: "bluetooth" description: "Refactor scan manager as described in go/scan-manager-refactor" diff --git a/flags/hal.aconfig b/flags/hal.aconfig index 3e16fa5355..0198e374c9 100644 --- a/flags/hal.aconfig +++ b/flags/hal.aconfig @@ -2,16 +2,6 @@ package: "com.android.bluetooth.flags" container: "com.android.bt" flag { - name: "audio_port_binder_inherit_rt" - namespace: "bluetooth" - description: "Allow audio port AIDL thread to inherit thread priority from its caller" - bug: "335049159" - metadata { - purpose: PURPOSE_BUGFIX - } -} - -flag { name: "snoop_logger_tracing" namespace: "bluetooth" description: "Add snoop logger tracing" @@ -29,4 +19,4 @@ flag { metadata { purpose: PURPOSE_BUGFIX } -}
\ No newline at end of file +} diff --git a/flags/l2cap.aconfig b/flags/l2cap.aconfig index bfbab82d6f..fec2edd6d5 100644 --- a/flags/l2cap.aconfig +++ b/flags/l2cap.aconfig @@ -9,13 +9,6 @@ flag { } flag { - name: "l2cap_p_ccb_check_rewrite" - namespace: "bluetooth" - description: "Rewrite logic of p_ccb check in l2c_link_sec_comp" - bug: "326686472" -} - -flag { name: "l2cap_le_do_not_adjust_min_interval" namespace: "bluetooth" description: "Do not adjust min_interval in connection update request" diff --git a/flags/pbapclient.aconfig b/flags/pbapclient.aconfig index 2464557d58..52b5ee3910 100644 --- a/flags/pbapclient.aconfig +++ b/flags/pbapclient.aconfig @@ -14,3 +14,13 @@ flag { description: "Use primary and secondary versions to persist contacts across connections" bug: "376461947" } + +flag { + name: "pbap_cleanup_use_handler" + namespace: "bluetooth" + description: "Use handler to prevent NPE from multi threading" + bug: "396306579" + metadata { + purpose: PURPOSE_BUGFIX + } +} diff --git a/framework/api/system-current.txt b/framework/api/system-current.txt index 60657262e3..10bdab4b5c 100644 --- a/framework/api/system-current.txt +++ b/framework/api/system-current.txt @@ -316,7 +316,7 @@ package android.bluetooth { field public static final int METADATA_COMPANION_APP = 4; // 0x4 field public static final int METADATA_DEVICE_TYPE = 17; // 0x11 field public static final int METADATA_ENHANCED_SETTINGS_UI_URI = 16; // 0x10 - field @FlaggedApi("com.android.bluetooth.flags.support_exclusive_manager") public static final int METADATA_EXCLUSIVE_MANAGER = 29; // 0x1d + field public static final int METADATA_EXCLUSIVE_MANAGER = 29; // 0x1d field public static final int METADATA_HARDWARE_VERSION = 3; // 0x3 field @FlaggedApi("com.android.bluetooth.flags.support_remote_device_metadata") public static final int METADATA_HEAD_UNIT_BUILD = 33; // 0x21 field @FlaggedApi("com.android.bluetooth.flags.support_remote_device_metadata") public static final int METADATA_HEAD_UNIT_MANUFACTURER_NAME = 31; // 0x1f diff --git a/framework/java/android/bluetooth/BluetoothDevice.java b/framework/java/android/bluetooth/BluetoothDevice.java index 439c9349cb..a4cacbf0a8 100644 --- a/framework/java/android/bluetooth/BluetoothDevice.java +++ b/framework/java/android/bluetooth/BluetoothDevice.java @@ -895,7 +895,6 @@ public final class BluetoothDevice implements Parcelable, Attributable { * * @hide */ - @FlaggedApi(Flags.FLAG_SUPPORT_EXCLUSIVE_MANAGER) @SystemApi public static final int METADATA_EXCLUSIVE_MANAGER = 29; diff --git a/framework/java/android/bluetooth/BluetoothLeBroadcastAssistant.java b/framework/java/android/bluetooth/BluetoothLeBroadcastAssistant.java index 683a5433ac..d8a5b4080e 100644 --- a/framework/java/android/bluetooth/BluetoothLeBroadcastAssistant.java +++ b/framework/java/android/bluetooth/BluetoothLeBroadcastAssistant.java @@ -916,7 +916,7 @@ public final class BluetoothLeBroadcastAssistant implements BluetoothProfile, Au @RequiresBluetoothScanPermission @RequiresPermission(allOf = {BLUETOOTH_SCAN, BLUETOOTH_PRIVILEGED}) public boolean isSearchInProgress() { - log("stopSearchingForSources:"); + log("isSearchInProgress:"); final IBluetoothLeBroadcastAssistant service = getService(); final boolean defaultValue = false; if (service == null) { diff --git a/framework/tests/bumble/src/android/bluetooth/hid/HidHostTest.java b/framework/tests/bumble/src/android/bluetooth/hid/HidHostTest.java index fc32341ef6..4661c98a75 100644 --- a/framework/tests/bumble/src/android/bluetooth/hid/HidHostTest.java +++ b/framework/tests/bumble/src/android/bluetooth/hid/HidHostTest.java @@ -112,6 +112,7 @@ public class HidHostTest { private static final int INVALID_RPT_ID = 3; private static final int CONNECTION_TIMEOUT_MS = 2_000; private static final int BT_ON_DELAY_MS = 3000; + private static final int REPORT_UPDATE_TIMEOUT_MS = 100; private static final Duration PROTO_MODE_TIMEOUT = Duration.ofSeconds(10); @@ -130,6 +131,7 @@ public class HidHostTest { @Mock private BroadcastReceiver mReceiver; private InOrder mInOrder = null; private byte[] mReportData = {}; + private CompletableFuture<Boolean> mIsReportUpdated; @Mock private BluetoothProfile.ServiceListener mProfileServiceListener; @SuppressLint("MissingPermission") @@ -239,6 +241,9 @@ public class HidHostTest { + device + " reportBufferSize " + reportBufferSize); + if (mIsReportUpdated != null) { + mIsReportUpdated.complete(true); + } break; case BluetoothDevice.ACTION_ACL_DISCONNECTED: device = @@ -595,22 +600,30 @@ public class HidHostTest { public void hidGetReportTest() throws Exception { // Keyboard report mReportData = new byte[0]; + mIsReportUpdated = new CompletableFuture<>(); mHidService.getReport(mDevice, BluetoothHidHost.REPORT_TYPE_INPUT, (byte) KEYBD_RPT_ID, 0); // Report Buffer = Report ID (1 byte) + Report Data (KEYBD_RPT_SIZE byte) verifyIntentReceived( hasAction(BluetoothHidHost.ACTION_REPORT), hasExtra(BluetoothHidHost.EXTRA_REPORT_BUFFER_SIZE, KEYBD_RPT_SIZE + 1)); + mIsReportUpdated + .completeOnTimeout(null, REPORT_UPDATE_TIMEOUT_MS, TimeUnit.MILLISECONDS) + .join(); assertThat(mReportData).isNotNull(); assertThat(mReportData.length).isGreaterThan(0); assertThat(mReportData[0]).isEqualTo(KEYBD_RPT_ID); // Mouse report mReportData = new byte[0]; + mIsReportUpdated = new CompletableFuture<>(); mHidService.getReport(mDevice, BluetoothHidHost.REPORT_TYPE_INPUT, (byte) MOUSE_RPT_ID, 0); // Report Buffer = Report ID (1 byte) + Report Data (MOUSE_RPT_SIZE byte) verifyIntentReceived( hasAction(BluetoothHidHost.ACTION_REPORT), hasExtra(BluetoothHidHost.EXTRA_REPORT_BUFFER_SIZE, MOUSE_RPT_SIZE + 1)); + mIsReportUpdated + .completeOnTimeout(null, REPORT_UPDATE_TIMEOUT_MS, TimeUnit.MILLISECONDS) + .join(); assertThat(mReportData).isNotNull(); assertThat(mReportData.length).isGreaterThan(0); assertThat(mReportData[0]).isEqualTo(MOUSE_RPT_ID); diff --git a/offload/hci/Android.bp b/offload/hci/Android.bp index bd396bcfe3..f9b5eb277e 100644 --- a/offload/hci/Android.bp +++ b/offload/hci/Android.bp @@ -50,6 +50,23 @@ rust_library { rust_test { name: "libbluetooth_offload_hci_test", host_supported: true, - test_suites: ["general-tests"], + target: { + android: { + test_config_template: ":BluetoothRustTestConfigTemplate", + test_suites: [ + "general-tests", + "mts-bt", + ], + }, + }, + compile_multilib: "both", + multilib: { + lib32: { + suffix: "32", + }, + lib64: { + suffix: "64", + }, + }, defaults: ["bluetooth_offload_hci_defaults"], } diff --git a/offload/leaudio/hci/Android.bp b/offload/leaudio/hci/Android.bp index 8a9b9247d6..0c7839bf91 100644 --- a/offload/leaudio/hci/Android.bp +++ b/offload/leaudio/hci/Android.bp @@ -42,6 +42,23 @@ rust_library { rust_test { name: "libbluetooth_offload_leaudio_hci_test", - test_suites: ["general-tests"], + target: { + android: { + test_config_template: ":BluetoothRustTestConfigTemplate", + test_suites: [ + "general-tests", + "mts-bt", + ], + }, + }, + compile_multilib: "both", + multilib: { + lib32: { + suffix: "32", + }, + lib64: { + suffix: "64", + }, + }, defaults: ["bluetooth_offload_leaudio_hci_defaults"], } diff --git a/rustfmt.toml b/rustfmt.toml index 05a76b507b..deeeb145aa 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -7,3 +7,4 @@ edition = "2021" use_small_heuristics = "Max" newline_style = "Unix" +imports_granularity = "Module" diff --git a/system/audio_bluetooth_hw/Android.bp b/system/audio_bluetooth_hw/Android.bp index fe2a441b78..1b8e850160 100644 --- a/system/audio_bluetooth_hw/Android.bp +++ b/system/audio_bluetooth_hw/Android.bp @@ -58,7 +58,10 @@ cc_library_shared { cc_test { name: "audio_bluetooth_hw_test", test_suites: ["general-tests"], - defaults: ["audio_bluetooth_hw_defaults"], + defaults: [ + "audio_bluetooth_hw_defaults", + "mts_defaults", + ], srcs: [ "utils.cc", "utils_unittest.cc", diff --git a/system/audio_hal_interface/Android.bp b/system/audio_hal_interface/Android.bp index 6382757832..81c3881025 100644 --- a/system/audio_hal_interface/Android.bp +++ b/system/audio_hal_interface/Android.bp @@ -92,6 +92,7 @@ cc_test { "latest_android_hardware_audio_common_ndk_static", "latest_android_hardware_bluetooth_audio_ndk_static", "latest_android_media_audio_common_types_ndk_static", + "mts_defaults", ], include_dirs: [ "packages/modules/Bluetooth/system", @@ -278,6 +279,7 @@ cc_test { "latest_android_hardware_audio_common_ndk_static", "latest_android_hardware_bluetooth_audio_ndk_static", "latest_android_media_audio_common_types_ndk_static", + "mts_defaults", ], include_dirs: [ "packages/modules/Bluetooth/system", @@ -328,6 +330,7 @@ cc_test { host_supported: true, defaults: [ "libbt_audio_hal_interface_test_defaults", + "mts_defaults", ], include_dirs: [ "packages/modules/Bluetooth/system/audio_hal_interface", @@ -365,6 +368,7 @@ cc_test { host_supported: true, defaults: [ "libbt_audio_hal_interface_test_defaults", + "mts_defaults", ], include_dirs: [ "packages/modules/Bluetooth/system/audio_hal_interface", diff --git a/system/audio_hal_interface/aidl/a2dp/bluetooth_audio_port_impl.cc b/system/audio_hal_interface/aidl/a2dp/bluetooth_audio_port_impl.cc index 29f5f70d47..3736805336 100644 --- a/system/audio_hal_interface/aidl/a2dp/bluetooth_audio_port_impl.cc +++ b/system/audio_hal_interface/aidl/a2dp/bluetooth_audio_port_impl.cc @@ -121,9 +121,7 @@ PresentationPosition::TimeSpec BluetoothAudioPortImpl::timespec_convert_to_hal(c // of the AIDL session / AudioFlinger writer thread. ndk::SpAIBinder BluetoothAudioPortImpl::createBinder() { auto binder = BnBluetoothAudioPort::createBinder(); - if (com::android::bluetooth::flags::audio_port_binder_inherit_rt()) { - AIBinder_setInheritRt(binder.get(), true); - } + AIBinder_setInheritRt(binder.get(), true); return binder; } diff --git a/system/audio_hal_interface/aidl/bluetooth_audio_port_impl.cc b/system/audio_hal_interface/aidl/bluetooth_audio_port_impl.cc index b9055deb9f..85f346f057 100644 --- a/system/audio_hal_interface/aidl/bluetooth_audio_port_impl.cc +++ b/system/audio_hal_interface/aidl/bluetooth_audio_port_impl.cc @@ -218,9 +218,7 @@ PresentationPosition::TimeSpec BluetoothAudioPortImpl::timespec_convert_to_hal(c // of the AIDL session / AudioFlinger writer thread. ndk::SpAIBinder BluetoothAudioPortImpl::createBinder() { auto binder = BnBluetoothAudioPort::createBinder(); - if (com::android::bluetooth::flags::audio_port_binder_inherit_rt()) { - AIBinder_setInheritRt(binder.get(), true); - } + AIBinder_setInheritRt(binder.get(), true); return binder; } diff --git a/system/bta/ar/bta_ar.cc b/system/bta/ar/bta_ar.cc index 8f41416ead..45e6010e31 100644 --- a/system/bta/ar/bta_ar.cc +++ b/system/bta/ar/bta_ar.cc @@ -201,58 +201,21 @@ void bta_ar_reg_avrc(uint16_t service_uuid, const char* service_name, const char return; } - if (com::android::bluetooth::flags::avrcp_sdp_records()) { - const std::shared_ptr<AvrcpSdpService>& avrcp_sdp_service = AvrcpSdpService::Get(); - AvrcpSdpRecord add_record_request = {service_uuid, - service_name, - provider_name, - categories, - browse_supported, - profile_version, - 0}; - if (service_uuid == UUID_SERVCLASS_AV_REM_CTRL_TARGET) { - avrcp_sdp_service->AddRecord(add_record_request, bta_ar_cb.sdp_tg_request_id); - log::debug("Assigned target request id {}", bta_ar_cb.sdp_tg_request_id); - } else if (service_uuid == UUID_SERVCLASS_AV_REMOTE_CONTROL || - service_uuid == UUID_SERVCLASS_AV_REM_CTRL_CONTROL) { - avrcp_sdp_service->AddRecord(add_record_request, bta_ar_cb.sdp_ct_request_id); - log::debug("Assigned control request id {}", bta_ar_cb.sdp_ct_request_id); - } - return; - } - uint8_t mask = BTA_AR_AV_MASK; - uint8_t temp[8], *p; - + const std::shared_ptr<AvrcpSdpService>& avrcp_sdp_service = AvrcpSdpService::Get(); + AvrcpSdpRecord add_record_request = {service_uuid, + service_name, + provider_name, + categories, + browse_supported, + profile_version, + 0}; if (service_uuid == UUID_SERVCLASS_AV_REM_CTRL_TARGET) { - if (bta_ar_cb.sdp_tg_handle == 0) { - bta_ar_cb.tg_registered = mask; - bta_ar_cb.sdp_tg_handle = get_legacy_stack_sdp_api()->handle.SDP_CreateRecord(); - AVRC_AddRecord(service_uuid, service_name, provider_name, categories, bta_ar_cb.sdp_tg_handle, - browse_supported, profile_version, 0); - bta_sys_add_uuid(service_uuid); - } - /* only one TG is allowed (first-come, first-served). - * If sdp_tg_handle is non-0, ignore this request */ - } else if ((service_uuid == UUID_SERVCLASS_AV_REMOTE_CONTROL) || - (service_uuid == UUID_SERVCLASS_AV_REM_CTRL_CONTROL)) { - bta_ar_cb.ct_categories[mask - 1] = categories; - categories = bta_ar_cb.ct_categories[0] | bta_ar_cb.ct_categories[1]; - if (bta_ar_cb.sdp_ct_handle == 0) { - bta_ar_cb.sdp_ct_handle = get_legacy_stack_sdp_api()->handle.SDP_CreateRecord(); - AVRC_AddRecord(service_uuid, service_name, provider_name, categories, bta_ar_cb.sdp_ct_handle, - browse_supported, profile_version, 0); - bta_sys_add_uuid(service_uuid); - } else { - /* multiple CTs are allowed. - * Change supported categories on the second one */ - p = temp; - UINT16_TO_BE_STREAM(p, categories); - if (!get_legacy_stack_sdp_api()->handle.SDP_AddAttribute( - bta_ar_cb.sdp_ct_handle, ATTR_ID_SUPPORTED_FEATURES, UINT_DESC_TYPE, (uint32_t)2, - (uint8_t*)temp)) { - log::warn("Unable to add supported features handle:{}", bta_ar_cb.sdp_ct_handle); - } - } + avrcp_sdp_service->AddRecord(add_record_request, bta_ar_cb.sdp_tg_request_id); + log::debug("Assigned target request id {}", bta_ar_cb.sdp_tg_request_id); + } else if (service_uuid == UUID_SERVCLASS_AV_REMOTE_CONTROL || + service_uuid == UUID_SERVCLASS_AV_REM_CTRL_CONTROL) { + avrcp_sdp_service->AddRecord(add_record_request, bta_ar_cb.sdp_ct_request_id); + log::debug("Assigned control request id {}", bta_ar_cb.sdp_ct_request_id); } } @@ -268,57 +231,17 @@ void bta_ar_reg_avrc(uint16_t service_uuid, const char* service_name, const char *****************************************************************************/ void bta_ar_dereg_avrc(uint16_t service_uuid) { log::verbose("Deregister AVRC 0x{:x}", service_uuid); - if (com::android::bluetooth::flags::avrcp_sdp_records()) { - const std::shared_ptr<AvrcpSdpService>& avrcp_sdp_service = AvrcpSdpService::Get(); - if (service_uuid == UUID_SERVCLASS_AV_REM_CTRL_TARGET && - bta_ar_cb.sdp_tg_request_id != UNASSIGNED_REQUEST_ID) { - avrcp_sdp_service->RemoveRecord(UUID_SERVCLASS_AV_REM_CTRL_TARGET, - bta_ar_cb.sdp_tg_request_id); - bta_ar_cb.sdp_tg_request_id = UNASSIGNED_REQUEST_ID; - } else if ((service_uuid == UUID_SERVCLASS_AV_REMOTE_CONTROL || - service_uuid == UUID_SERVCLASS_AV_REM_CTRL_CONTROL) && - bta_ar_cb.sdp_ct_request_id != UNASSIGNED_REQUEST_ID) { - avrcp_sdp_service->RemoveRecord(UUID_SERVCLASS_AV_REMOTE_CONTROL, - bta_ar_cb.sdp_ct_request_id); - bta_ar_cb.sdp_ct_request_id = UNASSIGNED_REQUEST_ID; - } - return; - } - uint8_t mask = BTA_AR_AV_MASK; - uint16_t categories = 0; - uint8_t temp[8], *p; - if (service_uuid == UUID_SERVCLASS_AV_REM_CTRL_TARGET) { - if (bta_ar_cb.sdp_tg_handle && mask == bta_ar_cb.tg_registered) { - bta_ar_cb.tg_registered = 0; - if (!get_legacy_stack_sdp_api()->handle.SDP_DeleteRecord(bta_ar_cb.sdp_tg_handle)) { - log::warn("Unable to delete SDP record handle:{}", bta_ar_cb.sdp_tg_handle); - } - bta_ar_cb.sdp_tg_handle = 0; - bta_sys_remove_uuid(service_uuid); - } - } else if (service_uuid == UUID_SERVCLASS_AV_REMOTE_CONTROL) { - if (bta_ar_cb.sdp_ct_handle) { - bta_ar_cb.ct_categories[mask - 1] = 0; - categories = bta_ar_cb.ct_categories[0] | bta_ar_cb.ct_categories[1]; - if (!categories) { - /* no CT is still registered - cleanup */ - if (get_legacy_stack_sdp_api()->handle.SDP_DeleteRecord(bta_ar_cb.sdp_ct_handle)) { - log::warn("Unable to delete SDP record handle:{}", bta_ar_cb.sdp_ct_handle); - } - bta_ar_cb.sdp_ct_handle = 0; - bta_sys_remove_uuid(service_uuid); - } else { - /* change supported categories to the remaining one */ - p = temp; - UINT16_TO_BE_STREAM(p, categories); - if (!get_legacy_stack_sdp_api()->handle.SDP_AddAttribute( - bta_ar_cb.sdp_ct_handle, ATTR_ID_SUPPORTED_FEATURES, UINT_DESC_TYPE, - (uint32_t)2, (uint8_t*)temp)) { - log::warn("Unable to add SDP supported features handle:{}", bta_ar_cb.sdp_ct_handle); - } - } - } + const std::shared_ptr<AvrcpSdpService>& avrcp_sdp_service = AvrcpSdpService::Get(); + if (service_uuid == UUID_SERVCLASS_AV_REM_CTRL_TARGET && + bta_ar_cb.sdp_tg_request_id != UNASSIGNED_REQUEST_ID) { + avrcp_sdp_service->RemoveRecord(UUID_SERVCLASS_AV_REM_CTRL_TARGET, bta_ar_cb.sdp_tg_request_id); + bta_ar_cb.sdp_tg_request_id = UNASSIGNED_REQUEST_ID; + } else if ((service_uuid == UUID_SERVCLASS_AV_REMOTE_CONTROL || + service_uuid == UUID_SERVCLASS_AV_REM_CTRL_CONTROL) && + bta_ar_cb.sdp_ct_request_id != UNASSIGNED_REQUEST_ID) { + avrcp_sdp_service->RemoveRecord(UUID_SERVCLASS_AV_REMOTE_CONTROL, bta_ar_cb.sdp_ct_request_id); + bta_ar_cb.sdp_ct_request_id = UNASSIGNED_REQUEST_ID; } } diff --git a/system/bta/av/bta_av_main.cc b/system/bta/av/bta_av_main.cc index 65ec7276c0..f32dea2bf2 100644 --- a/system/bta/av/bta_av_main.cc +++ b/system/bta/av/bta_av_main.cc @@ -512,38 +512,14 @@ static void bta_av_api_register(tBTA_AV_DATA* p_data) { */ bta_ar_reg_avct(); - if (com::android::bluetooth::flags::avrcp_sdp_records()) { - // Add target record for - // a) A2DP sink profile. or - // b) A2DP source profile only if new avrcp service is disabled. - if (profile_initialized == UUID_SERVCLASS_AUDIO_SINK || - (profile_initialized == UUID_SERVCLASS_AUDIO_SOURCE && !is_new_avrcp_enabled())) { - bta_ar_reg_avrc(UUID_SERVCLASS_AV_REM_CTRL_TARGET, "AV Remote Control Target", "", - p_bta_av_cfg->avrc_tg_cat, (bta_av_cb.features & BTA_AV_FEAT_BROWSE), - avrcp_version); - } - } else { - /* For the Audio Sink role we support additional TG to support - * absolute volume. - */ - if (is_new_avrcp_enabled()) { - log::verbose( - "newavrcp is the owner of the AVRCP Target SDP record. Don't " - "create the SDP record"); - } else { - log::verbose("newavrcp is not enabled. Create SDP record"); - - if (btif_av_src_sink_coexist_enabled()) { - bta_ar_reg_avrc_for_src_sink_coexist( - UUID_SERVCLASS_AV_REM_CTRL_TARGET, "AV Remote Control Target", NULL, - p_bta_av_cfg->avrc_tg_cat, static_cast<tBTA_SYS_ID>(BTA_ID_AV + local_role), - (bta_av_cb.features & BTA_AV_FEAT_BROWSE), avrcp_version); - } else { - bta_ar_reg_avrc(UUID_SERVCLASS_AV_REM_CTRL_TARGET, "AV Remote Control Target", NULL, - p_bta_av_cfg->avrc_tg_cat, (bta_av_cb.features & BTA_AV_FEAT_BROWSE), - avrcp_version); - } - } + // Add target record for + // a) A2DP sink profile. or + // b) A2DP source profile only if new avrcp service is disabled. + if (profile_initialized == UUID_SERVCLASS_AUDIO_SINK || + (profile_initialized == UUID_SERVCLASS_AUDIO_SOURCE && !is_new_avrcp_enabled())) { + bta_ar_reg_avrc(UUID_SERVCLASS_AV_REM_CTRL_TARGET, "AV Remote Control Target", "", + p_bta_av_cfg->avrc_tg_cat, bta_av_cb.features & BTA_AV_FEAT_BROWSE, + avrcp_version); } } @@ -672,56 +648,25 @@ static void bta_av_api_register(tBTA_AV_DATA* p_data) { bta_ar_reg_avct(); bta_av_rc_create(&bta_av_cb, AVCT_ROLE_ACCEPTOR, 0, BTA_AV_NUM_LINKS + 1); } - if (com::android::bluetooth::flags::avrcp_sdp_records()) { - // Add control record for sink profile. - // Also adds control record for source profile when new avrcp service is not enabled. - if (profile_initialized == UUID_SERVCLASS_AUDIO_SINK || - (profile_initialized == UUID_SERVCLASS_AUDIO_SOURCE && !is_new_avrcp_enabled())) { - uint16_t control_version = AVRC_GetControlProfileVersion(); - /* Create an SDP record as AVRC CT. We create 1.3 for SOURCE - * because we rely on feature bits being scanned by external - * devices more than the profile version itself. - */ - if (profile_initialized == UUID_SERVCLASS_AUDIO_SOURCE && !is_new_avrcp_enabled()) { - control_version = AVRC_REV_1_3; - } - if (!btif_av_src_sink_coexist_enabled() && - profile_initialized == UUID_SERVCLASS_AUDIO_SINK) { - control_version = AVRC_REV_1_6; - } - bta_ar_reg_avrc(UUID_SERVCLASS_AV_REMOTE_CONTROL, "AV Remote Control", "", - p_bta_av_cfg->avrc_ct_cat, (bta_av_cb.features & BTA_AV_FEAT_BROWSE), - control_version); - } - } else { - /* create an SDP record as AVRC CT. We create 1.3 for SOURCE + // Add control record for sink profile. + // Also adds control record for source profile when new avrcp service is not enabled. + if (profile_initialized == UUID_SERVCLASS_AUDIO_SINK || + (profile_initialized == UUID_SERVCLASS_AUDIO_SOURCE && !is_new_avrcp_enabled())) { + uint16_t control_version = AVRC_GetControlProfileVersion(); + /* Create an SDP record as AVRC CT. We create 1.3 for SOURCE * because we rely on feature bits being scanned by external * devices more than the profile version itself. - * - * We create 1.4 for SINK since we support browsing. */ - if (btif_av_src_sink_coexist_enabled()) { - if (profile_initialized == UUID_SERVCLASS_AUDIO_SOURCE) { - bta_ar_reg_avrc_for_src_sink_coexist( - UUID_SERVCLASS_AV_REMOTE_CONTROL, NULL, NULL, p_bta_av_cfg->avrc_ct_cat, - BTA_ID_AV, (bta_av_cb.features & BTA_AV_FEAT_BROWSE), AVRC_REV_1_5); - } else if (profile_initialized == UUID_SERVCLASS_AUDIO_SINK) { - bta_ar_reg_avrc_for_src_sink_coexist(UUID_SERVCLASS_AV_REMOTE_CONTROL, NULL, NULL, - p_bta_av_cfg->avrc_ct_cat, BTA_ID_AVK, - (bta_av_cb.features & BTA_AV_FEAT_BROWSE), - AVRC_GetControlProfileVersion()); - } - } else { - if (profile_initialized == UUID_SERVCLASS_AUDIO_SOURCE && !is_new_avrcp_enabled()) { - bta_ar_reg_avrc(UUID_SERVCLASS_AV_REMOTE_CONTROL, NULL, NULL, - p_bta_av_cfg->avrc_ct_cat, (bta_av_cb.features & BTA_AV_FEAT_BROWSE), - AVRC_REV_1_3); - } else if (profile_initialized == UUID_SERVCLASS_AUDIO_SINK) { - bta_ar_reg_avrc(UUID_SERVCLASS_AV_REMOTE_CONTROL, NULL, NULL, - p_bta_av_cfg->avrc_ct_cat, (bta_av_cb.features & BTA_AV_FEAT_BROWSE), - AVRC_REV_1_6); - } + if (profile_initialized == UUID_SERVCLASS_AUDIO_SOURCE && !is_new_avrcp_enabled()) { + control_version = AVRC_REV_1_3; + } + if (!btif_av_src_sink_coexist_enabled() && + profile_initialized == UUID_SERVCLASS_AUDIO_SINK) { + control_version = AVRC_REV_1_6; } + bta_ar_reg_avrc(UUID_SERVCLASS_AV_REMOTE_CONTROL, "AV Remote Control", "", + p_bta_av_cfg->avrc_ct_cat, bta_av_cb.features & BTA_AV_FEAT_BROWSE, + control_version); } } } diff --git a/system/bta/le_audio/state_machine.cc b/system/bta/le_audio/state_machine.cc index 6e401ebf24..1c991e624e 100644 --- a/system/bta/le_audio/state_machine.cc +++ b/system/bta/le_audio/state_machine.cc @@ -1375,6 +1375,8 @@ private: auto ase_audio_channel_allocation = ase->codec_config.GetAudioChannelAllocation(); params.audio_channel_allocation |= ase_audio_channel_allocation; + params.stream_config.bits_per_sample = ase->codec_config.GetBitsPerSample(); + auto address_with_type = leAudioDevice->GetAddressWithType(); auto info = ::bluetooth::le_audio::stream_map_info(ase->cis_conn_hdl, ase_audio_channel_allocation, true); diff --git a/system/bta/le_audio/state_machine_test.cc b/system/bta/le_audio/state_machine_test.cc index 91ee1ec915..284b498c63 100644 --- a/system/bta/le_audio/state_machine_test.cc +++ b/system/bta/le_audio/state_machine_test.cc @@ -5192,6 +5192,40 @@ TEST_F(StateMachineTestAdsp, testConfigureDataPathForAdsp) { // Prepare fake connected device group auto* group = PrepareSingleTestDeviceGroup(leaudio_group_id, context_type); + EXPECT_CALL(mock_callbacks_, + OnUpdatedCisConfiguration(group->group_id_, + bluetooth::le_audio::types::kLeAudioDirectionSink)) + .WillOnce([group](int group_id, uint8_t direction) { + ASSERT_EQ(group_id, group->group_id_); + + auto const& params = group->stream_conf.stream_params.get(direction); + ASSERT_NE(params.audio_channel_allocation, 0u); + ASSERT_NE(params.num_of_channels, 0u); + ASSERT_NE(params.num_of_devices, 0); + + auto stream_config = params.stream_config; + ASSERT_NE(stream_config.bits_per_sample, 0u); + ASSERT_NE(stream_config.sampling_frequency_hz, 0u); + ASSERT_NE(stream_config.frame_duration_us, 0u); + ASSERT_NE(stream_config.octets_per_codec_frame, 0u); + ASSERT_NE(stream_config.codec_frames_blocks_per_sdu, 0u); + ASSERT_NE(stream_config.peer_delay_ms, 0u); + ASSERT_NE(stream_config.stream_map.size(), 0lu); + + for (auto const& info : stream_config.stream_map) { + ASSERT_TRUE(info.is_stream_active); + ASSERT_EQ(codec_specific::kLc3CodingFormat, info.codec_config.id.coding_format); + ASSERT_EQ(0lu, info.codec_config.id.vendor_company_id); + ASSERT_EQ(0lu, info.codec_config.id.vendor_codec_id); + ASSERT_NE(info.address, RawAddress::kEmpty); + ASSERT_NE(info.stream_handle, 0); + ASSERT_NE(info.codec_config.params.Size(), 0lu); + ASSERT_NE(info.target_latency, 0); + ASSERT_NE(info.target_phy, 0); + ASSERT_NE(info.metadata.Size(), 0lu); + } + }); + /* Since we prepared device with Ringtone context in mind, only one ASE * should have been configured. */ @@ -5228,7 +5262,18 @@ TEST_F(StateMachineTestAdsp, testStreamConfigurationAdspDownMix) { .WillOnce([group](int group_id, uint8_t direction) { ASSERT_EQ(group_id, group->group_id_); - auto stream_config = group->stream_conf.stream_params.get(direction).stream_config; + auto const& params = group->stream_conf.stream_params.get(direction); + ASSERT_NE(params.audio_channel_allocation, 0u); + ASSERT_NE(params.num_of_channels, 0u); + ASSERT_NE(params.num_of_devices, 0); + + auto stream_config = params.stream_config; + ASSERT_NE(stream_config.bits_per_sample, 0u); + ASSERT_NE(stream_config.sampling_frequency_hz, 0u); + ASSERT_NE(stream_config.frame_duration_us, 0u); + ASSERT_NE(stream_config.octets_per_codec_frame, 0u); + ASSERT_NE(stream_config.codec_frames_blocks_per_sdu, 0u); + ASSERT_NE(stream_config.peer_delay_ms, 0u); ASSERT_NE(stream_config.stream_map.size(), 0lu); for (auto const& info : stream_config.stream_map) { @@ -5250,7 +5295,18 @@ TEST_F(StateMachineTestAdsp, testStreamConfigurationAdspDownMix) { .WillOnce([group](int group_id, uint8_t direction) { ASSERT_EQ(group_id, group->group_id_); - auto stream_config = group->stream_conf.stream_params.get(direction).stream_config; + auto const& params = group->stream_conf.stream_params.get(direction); + ASSERT_NE(params.audio_channel_allocation, 0u); + ASSERT_NE(params.num_of_channels, 0u); + ASSERT_NE(params.num_of_devices, 0); + + auto stream_config = params.stream_config; + ASSERT_NE(stream_config.bits_per_sample, 0u); + ASSERT_NE(stream_config.sampling_frequency_hz, 0u); + ASSERT_NE(stream_config.frame_duration_us, 0u); + ASSERT_NE(stream_config.octets_per_codec_frame, 0u); + ASSERT_NE(stream_config.codec_frames_blocks_per_sdu, 0u); + ASSERT_NE(stream_config.peer_delay_ms, 0u); ASSERT_NE(stream_config.stream_map.size(), 0lu); for (auto const& info : stream_config.stream_map) { diff --git a/system/btif/avrcp/avrcp_service.cc b/system/btif/avrcp/avrcp_service.cc index a1a4574d04..955d5cc4d6 100644 --- a/system/btif/avrcp/avrcp_service.cc +++ b/system/btif/avrcp/avrcp_service.cc @@ -397,40 +397,25 @@ void AvrcpService::Init(MediaInterface* media_interface, VolumeInterface* volume profile_version = avrcp_interface_.GetAvrcpVersion(); uint16_t supported_features = GetSupportedFeatures(profile_version); - if (com::android::bluetooth::flags::avrcp_sdp_records()) { - const std::shared_ptr<AvrcpSdpService>& avrcp_sdp_service = AvrcpSdpService::Get(); - AvrcpSdpRecord target_add_record_request = {UUID_SERVCLASS_AV_REM_CTRL_TARGET, - "AV Remote Control Target", - "", - supported_features, - true, - profile_version, - 0}; - avrcp_sdp_service->AddRecord(target_add_record_request, target_sdp_request_id_); - log::verbose("Target request id {}", target_sdp_request_id_); - AvrcpSdpRecord control_add_record_request = {UUID_SERVCLASS_AV_REMOTE_CONTROL, - "AV Remote Control", - "", - AVRCP_SUPF_TG_CT, - false, - avrcp_interface_.GetAvrcpControlVersion(), - 0}; - avrcp_sdp_service->AddRecord(control_add_record_request, control_sdp_request_id_); - log::verbose("Control request id {}", control_sdp_request_id_); - } else { - sdp_record_handle = get_legacy_stack_sdp_api()->handle.SDP_CreateRecord(); - - avrcp_interface_.AddRecord(UUID_SERVCLASS_AV_REM_CTRL_TARGET, "AV Remote Control Target", NULL, - supported_features, sdp_record_handle, true, profile_version, 0); - bta_sys_add_uuid(UUID_SERVCLASS_AV_REM_CTRL_TARGET); - - ct_sdp_record_handle = get_legacy_stack_sdp_api()->handle.SDP_CreateRecord(); - - avrcp_interface_.AddRecord(UUID_SERVCLASS_AV_REMOTE_CONTROL, "AV Remote Control", NULL, - AVRCP_SUPF_TG_CT, ct_sdp_record_handle, false, - avrcp_interface_.GetAvrcpControlVersion(), 0); - bta_sys_add_uuid(UUID_SERVCLASS_AV_REMOTE_CONTROL); - } + const std::shared_ptr<AvrcpSdpService>& avrcp_sdp_service = AvrcpSdpService::Get(); + AvrcpSdpRecord target_add_record_request = {UUID_SERVCLASS_AV_REM_CTRL_TARGET, + "AV Remote Control Target", + "", + supported_features, + true, + profile_version, + 0}; + avrcp_sdp_service->AddRecord(target_add_record_request, target_sdp_request_id_); + log::verbose("Target request id {}", target_sdp_request_id_); + AvrcpSdpRecord control_add_record_request = {UUID_SERVCLASS_AV_REMOTE_CONTROL, + "AV Remote Control", + "", + AVRCP_SUPF_TG_CT, + false, + avrcp_interface_.GetAvrcpControlVersion(), + 0}; + avrcp_sdp_service->AddRecord(control_add_record_request, control_sdp_request_id_); + log::verbose("Control request id {}", control_sdp_request_id_); media_interface_ = new MediaInterfaceWrapper(media_interface); media_interface->RegisterUpdateCallback(instance_); @@ -472,20 +457,13 @@ uint16_t AvrcpService::GetSupportedFeatures(uint16_t profile_version) { void AvrcpService::Cleanup() { log::info("AVRCP Target Service stopped"); - if (com::android::bluetooth::flags::avrcp_sdp_records()) { - const std::shared_ptr<AvrcpSdpService>& avrcp_sdp_service = AvrcpSdpService::Get(); - avrcp_sdp_service->RemoveRecord(UUID_SERVCLASS_AV_REM_CTRL_TARGET, target_sdp_request_id_); - target_sdp_request_id_ = UNASSIGNED_REQUEST_ID; - avrcp_sdp_service->RemoveRecord(UUID_SERVCLASS_AV_REMOTE_CONTROL, control_sdp_request_id_); - control_sdp_request_id_ = UNASSIGNED_REQUEST_ID; - } else { - avrcp_interface_.RemoveRecord(sdp_record_handle); - bta_sys_remove_uuid(UUID_SERVCLASS_AV_REM_CTRL_TARGET); - sdp_record_handle = -1; - avrcp_interface_.RemoveRecord(ct_sdp_record_handle); - bta_sys_remove_uuid(UUID_SERVCLASS_AV_REMOTE_CONTROL); - ct_sdp_record_handle = -1; - } + + const std::shared_ptr<AvrcpSdpService>& avrcp_sdp_service = AvrcpSdpService::Get(); + avrcp_sdp_service->RemoveRecord(UUID_SERVCLASS_AV_REM_CTRL_TARGET, target_sdp_request_id_); + target_sdp_request_id_ = UNASSIGNED_REQUEST_ID; + avrcp_sdp_service->RemoveRecord(UUID_SERVCLASS_AV_REMOTE_CONTROL, control_sdp_request_id_); + control_sdp_request_id_ = UNASSIGNED_REQUEST_ID; + connection_handler_->CleanUp(); connection_handler_ = nullptr; if (player_settings_interface_ != nullptr) { @@ -499,32 +477,17 @@ void AvrcpService::Cleanup() { void AvrcpService::RegisterBipServer(int psm) { log::info("AVRCP Target Service has registered a BIP OBEX server, psm={}", psm); - if (com::android::bluetooth::flags::avrcp_sdp_records()) { - const std::shared_ptr<AvrcpSdpService>& avrcp_sdp_service = AvrcpSdpService::Get(); - avrcp_sdp_service->EnableCovertArt(UUID_SERVCLASS_AV_REM_CTRL_TARGET, psm, - target_sdp_request_id_); - } else { - avrcp_interface_.RemoveRecord(sdp_record_handle); - uint16_t supported_features = - GetSupportedFeatures(profile_version) | AVRC_SUPF_TG_PLAYER_COVER_ART; - sdp_record_handle = get_legacy_stack_sdp_api()->handle.SDP_CreateRecord(); - avrcp_interface_.AddRecord(UUID_SERVCLASS_AV_REM_CTRL_TARGET, "AV Remote Control Target", NULL, - supported_features, sdp_record_handle, true, profile_version, psm); - } + + const std::shared_ptr<AvrcpSdpService>& avrcp_sdp_service = AvrcpSdpService::Get(); + avrcp_sdp_service->EnableCovertArt(UUID_SERVCLASS_AV_REM_CTRL_TARGET, psm, + target_sdp_request_id_); } void AvrcpService::UnregisterBipServer() { log::info("AVRCP Target Service has unregistered a BIP OBEX server"); - if (com::android::bluetooth::flags::avrcp_sdp_records()) { - const std::shared_ptr<AvrcpSdpService>& avrcp_sdp_service = AvrcpSdpService::Get(); - avrcp_sdp_service->DisableCovertArt(UUID_SERVCLASS_AV_REM_CTRL_TARGET, target_sdp_request_id_); - } else { - avrcp_interface_.RemoveRecord(sdp_record_handle); - uint16_t supported_features = GetSupportedFeatures(profile_version); - sdp_record_handle = get_legacy_stack_sdp_api()->handle.SDP_CreateRecord(); - avrcp_interface_.AddRecord(UUID_SERVCLASS_AV_REM_CTRL_TARGET, "AV Remote Control Target", NULL, - supported_features, sdp_record_handle, true, profile_version, 0); - } + + const std::shared_ptr<AvrcpSdpService>& avrcp_sdp_service = AvrcpSdpService::Get(); + avrcp_sdp_service->DisableCovertArt(UUID_SERVCLASS_AV_REM_CTRL_TARGET, target_sdp_request_id_); avrcp_interface_.RemoveRecord(sdp_record_handle); uint16_t supported_features = GetSupportedFeatures(profile_version); sdp_record_handle = get_legacy_stack_sdp_api()->handle.SDP_CreateRecord(); diff --git a/system/btif/src/btif_dm.cc b/system/btif/src/btif_dm.cc index 73da86b009..d169837c23 100644 --- a/system/btif/src/btif_dm.cc +++ b/system/btif/src/btif_dm.cc @@ -542,6 +542,13 @@ static bool check_sdp_bl(const RawAddress* remote_bdaddr) { return false; } +static void wipe_le_audio_metadata_cache_for_pairing_device() { + if (!pairing_cb.static_bdaddr.IsEmpty()) { + metadata_cb.le_audio_cache.extract(pairing_cb.static_bdaddr); + } + metadata_cb.le_audio_cache.extract(pairing_cb.bd_addr); +} + static void bond_state_changed(bt_status_t status, const RawAddress& bd_addr, bt_bond_state_t state) { btif_stats_add_bond_event(bd_addr, BTIF_DM_FUNC_BOND_STATE_CHANGED, state); @@ -597,6 +604,7 @@ static void bond_state_changed(bt_status_t status, const RawAddress& bd_addr, pairing_cb.bd_addr = bd_addr; } else { log::debug("clearing btif pairing_cb"); + wipe_le_audio_metadata_cache_for_pairing_device(); pairing_cb = {}; } } @@ -1671,6 +1679,7 @@ static void btif_on_service_discovery_results(RawAddress bd_addr, if (!skip_reporting_wait_for_le) { // Both SDP and bonding are done, clear pairing control block in case // it is not already cleared + wipe_le_audio_metadata_cache_for_pairing_device(); pairing_cb = {}; log::debug("clearing btif pairing_cb"); } @@ -1720,6 +1729,7 @@ static void btif_on_gatt_results(RawAddress bd_addr, std::vector<bluetooth::Uuid // Both SDP and bonding are either done, or not scheduled, // we are safe to clear the service discovery part of CB. log::debug("clearing pairing_cb"); + wipe_le_audio_metadata_cache_for_pairing_device(); pairing_cb = {}; } @@ -1964,6 +1974,7 @@ void BTIF_dm_enable() { } } /* clear control blocks */ + wipe_le_audio_metadata_cache_for_pairing_device(); pairing_cb = {}; pairing_cb.bond_type = BOND_TYPE_PERSISTENT; diff --git a/system/build/Android.bp b/system/build/Android.bp index 13f1ccccf5..a34d0a1ed4 100644 --- a/system/build/Android.bp +++ b/system/build/Android.bp @@ -20,7 +20,7 @@ cc_defaults { ], target: { android: { - test_config_template: ":BluetoothTestConfigTemplate", + test_config_template: ":BluetoothGTestConfigTemplate", sanitize: { misc_undefined: ["bounds"], }, diff --git a/system/conf/interop_database.conf b/system/conf/interop_database.conf index 92178616d4..ecf3da0b07 100644 --- a/system/conf/interop_database.conf +++ b/system/conf/interop_database.conf @@ -207,6 +207,8 @@ ELECOM = Name_Based Dexcom = Name_Based DXCM = Name_Based DX0 = Name_Based +NMI = Name_Based +NM2 = Name_Based # Disable role switch for headsets/car-kits # Some car kits allow role switch but when DUT initiates role switch diff --git a/system/device/test/interop_test.cc b/system/device/test/interop_test.cc index 707a7b0972..c3737c4912 100644 --- a/system/device/test/interop_test.cc +++ b/system/device/test/interop_test.cc @@ -368,6 +368,8 @@ TEST_F(InteropTest, test_name_hit) { EXPECT_TRUE(interop_match_name(INTEROP_DISABLE_LE_CONN_PREFERRED_PARAMS, "DXCMog")); EXPECT_TRUE(interop_match_name(INTEROP_DISABLE_LE_CONN_PREFERRED_PARAMS, "Dexcom 123")); EXPECT_TRUE(interop_match_name(INTEROP_DISABLE_LE_CONN_PREFERRED_PARAMS, "DX01ab")); + EXPECT_TRUE(interop_match_name(INTEROP_DISABLE_LE_CONN_PREFERRED_PARAMS, "NMIabc")); + EXPECT_TRUE(interop_match_name(INTEROP_DISABLE_LE_CONN_PREFERRED_PARAMS, "NM2XYZ")); EXPECT_TRUE(interop_match_name(INTEROP_DISABLE_AAC_CODEC, "abramtek M1")); EXPECT_TRUE(interop_match_name(INTEROP_DISABLE_AAC_VBR_CODEC, "Audi_MMI_2781")); EXPECT_TRUE(interop_match_name(INTEROP_DISABLE_AVDTP_RECONFIGURE, "KMM-BT51*HD")); diff --git a/system/gd/hal/snoop_logger_test.cc b/system/gd/hal/snoop_logger_test.cc index 54e0e159aa..1f4d2daa64 100644 --- a/system/gd/hal/snoop_logger_test.cc +++ b/system/gd/hal/snoop_logger_test.cc @@ -1543,10 +1543,13 @@ TEST_F(SnoopLoggerModuleTest, recreate_log_directory_when_enabled_test) { ASSERT_TRUE(std::filesystem::exists(temp_log_btsnoop_file_)); // btsnooz file should be removed as snoop_log_persists is false ASSERT_FALSE(std::filesystem::exists(temp_log_btsnooz_file_)); - // remove after test + // remove temp_dir_path_ contents after test if (std::filesystem::exists(temp_dir_path_)) { - std::filesystem::remove_all(temp_dir_path_); + for (const auto& entry : std::filesystem::directory_iterator(temp_dir_path_)) { + std::filesystem::remove_all(entry.path()); + } } + ASSERT_TRUE(std::filesystem::exists(temp_dir_path_)); } TEST_F(SnoopLoggerModuleTest, recreate_log_directory_when_filtered_test) { @@ -1585,10 +1588,13 @@ TEST_F(SnoopLoggerModuleTest, recreate_log_directory_when_filtered_test) { ASSERT_TRUE(std::filesystem::exists(temp_log_btsnoop_filtered_file_)); // btsnooz file should be removed as snoop_log_persists is false ASSERT_FALSE(std::filesystem::exists(temp_log_btsnooz_filtered_file_)); - // remove after test + // remove temp_dir_path_ contents after test if (std::filesystem::exists(temp_dir_path_)) { - std::filesystem::remove_all(temp_dir_path_); + for (const auto& entry : std::filesystem::directory_iterator(temp_dir_path_)) { + std::filesystem::remove_all(entry.path()); + } } + ASSERT_TRUE(std::filesystem::exists(temp_dir_path_)); } #endif // __ANDROID__ diff --git a/system/gd/hci/acl_manager/acl_scheduler.cc b/system/gd/hci/acl_manager/acl_scheduler.cc index 320373593b..f7c47505af 100644 --- a/system/gd/hci/acl_manager/acl_scheduler.cc +++ b/system/gd/hci/acl_manager/acl_scheduler.cc @@ -170,13 +170,11 @@ private: if (pending_outgoing_operations_.empty()) { return false; } - if (com::android::bluetooth::flags::progress_acl_scheduler_upon_incoming_connection()) { - if (const RemoteNameRequestQueueEntry* peek = - std::get_if<RemoteNameRequestQueueEntry>(&pending_outgoing_operations_.front())) { - if (incoming_connecting_address_set_.contains(peek->address)) { - log::info("Pending incoming connection and outgoing RNR to same peer:{}", peek->address); - return true; - } + if (const RemoteNameRequestQueueEntry* peek = + std::get_if<RemoteNameRequestQueueEntry>(&pending_outgoing_operations_.front())) { + if (incoming_connecting_address_set_.contains(peek->address)) { + log::info("Pending incoming connection and outgoing RNR to same peer:{}", peek->address); + return true; } } return incoming_connecting_address_set_.empty() && !outgoing_entry_.has_value(); diff --git a/system/gd/hci/acl_manager/acl_scheduler_test.cc b/system/gd/hci/acl_manager/acl_scheduler_test.cc index f09a14c836..afdddcd3a7 100644 --- a/system/gd/hci/acl_manager/acl_scheduler_test.cc +++ b/system/gd/hci/acl_manager/acl_scheduler_test.cc @@ -291,9 +291,7 @@ TEST_F(AclSchedulerTest, DoNothingWhileIncomingConnectionsExist) { EXPECT_THAT(future, IsSet()); } -TEST_F_WITH_FLAGS(AclSchedulerTest, IncomingConnectionPendingWithOutgoingRemoteNameRequest, - REQUIRES_FLAGS_ENABLED( - ACONFIG_FLAG(TEST_BT, progress_acl_scheduler_upon_incoming_connection))) { +TEST_F(AclSchedulerTest, IncomingConnectionPendingWithOutgoingRemoteNameRequest) { auto promise = std::promise<void>{}; auto future = promise.get_future(); @@ -308,9 +306,7 @@ TEST_F_WITH_FLAGS(AclSchedulerTest, IncomingConnectionPendingWithOutgoingRemoteN EXPECT_THAT(future, IsSet()); } -TEST_F_WITH_FLAGS(AclSchedulerTest, ConnectionToSameDeviceIncomingConnectionPending, - REQUIRES_FLAGS_ENABLED( - ACONFIG_FLAG(TEST_BT, progress_acl_scheduler_upon_incoming_connection))) { +TEST_F(AclSchedulerTest, ConnectionToSameDeviceIncomingConnectionPending) { auto promise = std::promise<void>{}; auto future = promise.get_future(); diff --git a/system/gd/hci/le_scanning_manager.cc b/system/gd/hci/le_scanning_manager.cc index 742280658a..e80caaf23c 100644 --- a/system/gd/hci/le_scanning_manager.cc +++ b/system/gd/hci/le_scanning_manager.cc @@ -354,17 +354,10 @@ struct LeScanningManager::impl : public LeAddressManagerCallback { extended_event_type = transform_to_extended_event_type({.legacy = true}); break; case AdvertisingEventType::SCAN_RESPONSE: - if (com::android::bluetooth::flags::fix_nonconnectable_scannable_advertisement()) { - // We don't know if the initial advertising report was connectable or not. - // LeScanningReassembler fixes the connectable field. - extended_event_type = transform_to_extended_event_type( - {.scannable = true, .scan_response = true, .legacy = true}); - } else { - extended_event_type = transform_to_extended_event_type({.connectable = true, - .scannable = true, - .scan_response = true, - .legacy = true}); - } + // We don't know if the initial advertising report was connectable or not. + // LeScanningReassembler fixes the connectable field. + extended_event_type = transform_to_extended_event_type( + {.scannable = true, .scan_response = true, .legacy = true}); break; default: log::warn("Unsupported event type:{}", (uint16_t)report.event_type_); @@ -441,15 +434,10 @@ struct LeScanningManager::impl : public LeAddressManagerCallback { break; } - const uint16_t result_event_type = - com::android::bluetooth::flags::fix_nonconnectable_scannable_advertisement() - ? processed_report->extended_event_type - : event_type; - scanning_callbacks_->OnScanResult( - result_event_type, address_type, address, primary_phy, secondary_phy, advertising_sid, - tx_power, get_rssi_after_calibration(rssi), periodic_advertising_interval, - std::move(processed_report->data)); + processed_report->extended_event_type, address_type, address, primary_phy, + secondary_phy, advertising_sid, tx_power, get_rssi_after_calibration(rssi), + periodic_advertising_interval, std::move(processed_report->data)); } } diff --git a/system/gd/hci/le_scanning_manager_test.cc b/system/gd/hci/le_scanning_manager_test.cc index 9419b2f66b..7eab705d0f 100644 --- a/system/gd/hci/le_scanning_manager_test.cc +++ b/system/gd/hci/le_scanning_manager_test.cc @@ -383,9 +383,6 @@ TEST_F(LeScanningManagerTest, legacy_adv_scan_ind_report_with_scan_response) { // The 'connectable' bit should NOT be set. uint16_t extended_event_type = kLegacy | kScannable | kScanResponse; - if (!com::android::bluetooth::flags::fix_nonconnectable_scannable_advertisement()) { - extended_event_type |= kConnectable; - } EXPECT_CALL(mock_callbacks_, OnScanResult(extended_event_type, _, _, _, _, _, _, _, _, _)); test_hci_layer_->IncomingLeMetaEvent(LeAdvertisingReportBuilder::Create({scan_response})); diff --git a/system/log/Android.bp b/system/log/Android.bp index e0855a2304..47e13b59ea 100644 --- a/system/log/Android.bp +++ b/system/log/Android.bp @@ -34,13 +34,17 @@ cc_library { cc_test { name: "libbluetooth_log_test", test_suites: ["general-tests"], + defaults: ["mts_defaults"], host_supported: true, srcs: [ "src/truncating_buffer_test.cc", "src/vlog_test.cc", ], + static_libs: [ + "libbluetooth_log", + ], shared_libs: [ "libbase", - "libbluetooth_log", + "liblog", ], } diff --git a/system/rust/Android.bp b/system/rust/Android.bp index d005b23c77..344da0728d 100644 --- a/system/rust/Android.bp +++ b/system/rust/Android.bp @@ -58,6 +58,11 @@ rust_defaults { rustlibs: [ "libandroid_logger", ], + test_config_template: ":BluetoothRustTestConfigTemplate", + test_suites: [ + "general-tests", + "mts-bt", + ], }, host: { rustlibs: [ @@ -68,7 +73,19 @@ rust_defaults { enabled: false, }, }, - apex_available: ["com.android.bt"], + compile_multilib: "both", + multilib: { + lib32: { + suffix: "32", + }, + lib64: { + suffix: "64", + }, + }, + apex_available: [ + "//apex_available:platform", + "com.android.bt", + ], } rust_ffi_static { @@ -92,7 +109,6 @@ rust_ffi_static { rust_test { name: "libbluetooth_core_rs_test", host_supported: true, - test_suites: ["general-tests"], defaults: ["libbluetooth_core_rs_defaults"], rustlibs: [ "libbluetooth_aconfig_flags_rust", diff --git a/system/rust/build.rs b/system/rust/build.rs index bae31cdcaa..08cb84c6a2 100644 --- a/system/rust/build.rs +++ b/system/rust/build.rs @@ -2,7 +2,10 @@ //! //! Run `cargo install --path .` in `external/rust/crates/pdl-compiler` to ensure `pdlc` //! is in your path. -use std::{env, fs::File, io::Write, path::Path}; +use std::env; +use std::fs::File; +use std::io::Write; +use std::path::Path; fn main() { let out_dir = env::var_os("OUT_DIR").unwrap(); diff --git a/system/rust/src/core/mod.rs b/system/rust/src/core/mod.rs index e4f4932b79..ebcd65c353 100644 --- a/system/rust/src/core/mod.rs +++ b/system/rust/src/core/mod.rs @@ -10,10 +10,8 @@ use std::pin::Pin; use cxx::UniquePtr; -use crate::{ - gatt::ffi::{AttTransportImpl, GattCallbacksImpl}, - RustModuleRunner, -}; +use crate::gatt::ffi::{AttTransportImpl, GattCallbacksImpl}; +use crate::RustModuleRunner; use self::ffi::{future_ready, Future, GattServerCallbacks}; diff --git a/system/rust/src/core/shared_box.rs b/system/rust/src/core/shared_box.rs index accd1ae6ec..2f28c79c68 100644 --- a/system/rust/src/core/shared_box.rs +++ b/system/rust/src/core/shared_box.rs @@ -5,10 +5,8 @@ //! not be held across async points. This reduces the risk of accidental //! lifetime extension. -use std::{ - ops::Deref, - rc::{Rc, Weak}, -}; +use std::ops::Deref; +use std::rc::{Rc, Weak}; /// A Box<> where static "weak" references to the contents can be taken, /// and fallibly upgraded at a later point. Unlike Rc<>, weak references diff --git a/system/rust/src/core/shared_mutex.rs b/system/rust/src/core/shared_mutex.rs index 8477932601..ef28223495 100644 --- a/system/rust/src/core/shared_mutex.rs +++ b/system/rust/src/core/shared_mutex.rs @@ -1,7 +1,9 @@ //! The motivation for SharedMutex is to guard a resource without having to //! extend its lifetime using an Rc<> (and potentially create reference cycles) -use std::{future::Future, rc::Rc, sync::Arc}; +use std::future::Future; +use std::rc::Rc; +use std::sync::Arc; use tokio::sync::{Mutex, OwnedMutexGuard, Semaphore, TryLockError}; diff --git a/system/rust/src/gatt/arbiter.rs b/system/rust/src/gatt/arbiter.rs index f25250043b..3abe6d2ff3 100644 --- a/system/rust/src/gatt/arbiter.rs +++ b/system/rust/src/gatt/arbiter.rs @@ -7,15 +7,14 @@ use std::sync::{Arc, Mutex}; use log::{error, trace, warn}; use std::sync::RwLock; -use crate::{do_in_rust_thread, packets::att}; +use crate::do_in_rust_thread; +use crate::packets::att; -use super::{ - ffi::{InterceptAction, StoreCallbacksFromRust}, - ids::{AdvertiserId, TransportIndex}, - mtu::MtuEvent, - opcode_types::{classify_opcode, OperationType}, - server::isolation_manager::IsolationManager, -}; +use super::ffi::{InterceptAction, StoreCallbacksFromRust}; +use super::ids::{AdvertiserId, TransportIndex}; +use super::mtu::MtuEvent; +use super::opcode_types::{classify_opcode, OperationType}; +use super::server::isolation_manager::IsolationManager; static ARBITER: RwLock<Option<Arc<Mutex<IsolationManager>>>> = RwLock::new(None); @@ -156,10 +155,8 @@ fn on_mtu_event(tcb_idx: TransportIndex, event: MtuEvent) { mod test { use super::*; - use crate::{ - gatt::ids::{AttHandle, ServerId}, - packets::att, - }; + use crate::gatt::ids::{AttHandle, ServerId}; + use crate::packets::att; const TCB_IDX: TransportIndex = TransportIndex(1); const ADVERTISER_ID: AdvertiserId = AdvertiserId(3); diff --git a/system/rust/src/gatt/callbacks.rs b/system/rust/src/gatt/callbacks.rs index 377d5a81f6..41b81a4f35 100644 --- a/system/rust/src/gatt/callbacks.rs +++ b/system/rust/src/gatt/callbacks.rs @@ -11,11 +11,9 @@ use log::warn; use crate::packets::att::AttErrorCode; -use super::{ - ffi::AttributeBackingType, - ids::{AttHandle, ConnectionId, TransactionId, TransportIndex}, - server::IndicationError, -}; +use super::ffi::AttributeBackingType; +use super::ids::{AttHandle, ConnectionId, TransactionId, TransportIndex}; +use super::server::IndicationError; /// These callbacks are expected to be made available to the GattModule from /// JNI. @@ -209,12 +207,11 @@ impl<T: GattDatastore + ?Sized> RawGattDatastore for T { #[cfg(test)] mod test { - use tokio::{sync::mpsc::error::TryRecvError, task::spawn_local}; + use tokio::sync::mpsc::error::TryRecvError; + use tokio::task::spawn_local; - use crate::{ - gatt::mocks::mock_datastore::{MockDatastore, MockDatastoreEvents}, - utils::task::block_on_locally, - }; + use crate::gatt::mocks::mock_datastore::{MockDatastore, MockDatastoreEvents}; + use crate::utils::task::block_on_locally; use super::*; diff --git a/system/rust/src/gatt/callbacks/callback_transaction_manager.rs b/system/rust/src/gatt/callbacks/callback_transaction_manager.rs index f877f17d81..f00a6a4f42 100644 --- a/system/rust/src/gatt/callbacks/callback_transaction_manager.rs +++ b/system/rust/src/gatt/callbacks/callback_transaction_manager.rs @@ -1,16 +1,16 @@ -use std::{cell::RefCell, collections::HashMap, rc::Rc, time::Duration}; +use std::cell::RefCell; +use std::collections::HashMap; +use std::rc::Rc; +use std::time::Duration; use async_trait::async_trait; use log::{trace, warn}; -use tokio::{sync::oneshot, time::timeout}; - -use crate::{ - gatt::{ - ids::{AttHandle, ConnectionId, ServerId, TransactionId, TransportIndex}, - GattCallbacks, - }, - packets::att::AttErrorCode, -}; +use tokio::sync::oneshot; +use tokio::time::timeout; + +use crate::gatt::ids::{AttHandle, ConnectionId, ServerId, TransactionId, TransportIndex}; +use crate::gatt::GattCallbacks; +use crate::packets::att::AttErrorCode; use super::{ AttributeBackingType, GattWriteRequestType, GattWriteType, RawGattDatastore, diff --git a/system/rust/src/gatt/ffi.rs b/system/rust/src/gatt/ffi.rs index 4a54dd9f71..8afbdd88e2 100644 --- a/system/rust/src/gatt/ffi.rs +++ b/system/rust/src/gatt/ffi.rs @@ -1,8 +1,7 @@ //! FFI interfaces for the GATT module. Some structs are exported so that //! core::init can instantiate and pass them into the main loop. -use pdl_runtime::EncodeError; -use pdl_runtime::Packet; +use pdl_runtime::{EncodeError, Packet}; use std::iter::Peekable; use anyhow::{bail, Result}; @@ -11,25 +10,18 @@ pub use inner::*; use log::{error, info, trace, warn}; use tokio::task::spawn_local; -use crate::{ - do_in_rust_thread, - packets::att::{self, AttErrorCode}, -}; +use crate::do_in_rust_thread; +use crate::packets::att::{self, AttErrorCode}; -use super::{ - arbiter::with_arbiter, - callbacks::{GattWriteRequestType, GattWriteType, TransactionDecision}, - channel::AttTransport, - ids::{AdvertiserId, AttHandle, ConnectionId, ServerId, TransactionId, TransportIndex}, - server::{ - gatt_database::{ - AttPermissions, GattCharacteristicWithHandle, GattDescriptorWithHandle, - GattServiceWithHandle, - }, - IndicationError, - }, - GattCallbacks, +use super::arbiter::with_arbiter; +use super::callbacks::{GattWriteRequestType, GattWriteType, TransactionDecision}; +use super::channel::AttTransport; +use super::ids::{AdvertiserId, AttHandle, ConnectionId, ServerId, TransactionId, TransportIndex}; +use super::server::gatt_database::{ + AttPermissions, GattCharacteristicWithHandle, GattDescriptorWithHandle, GattServiceWithHandle, }; +use super::server::IndicationError; +use super::GattCallbacks; #[cxx::bridge] #[allow(clippy::needless_lifetimes)] diff --git a/system/rust/src/gatt/mocks/mock_callbacks.rs b/system/rust/src/gatt/mocks/mock_callbacks.rs index 14a8da7a6b..cb81487e63 100644 --- a/system/rust/src/gatt/mocks/mock_callbacks.rs +++ b/system/rust/src/gatt/mocks/mock_callbacks.rs @@ -1,12 +1,10 @@ //! Mocked implementation of GattCallbacks for use in test -use crate::gatt::{ - callbacks::{GattWriteType, TransactionDecision}, - ffi::AttributeBackingType, - ids::{AttHandle, ConnectionId, TransactionId}, - server::IndicationError, - GattCallbacks, -}; +use crate::gatt::callbacks::{GattWriteType, TransactionDecision}; +use crate::gatt::ffi::AttributeBackingType; +use crate::gatt::ids::{AttHandle, ConnectionId, TransactionId}; +use crate::gatt::server::IndicationError; +use crate::gatt::GattCallbacks; use tokio::sync::mpsc::{self, unbounded_channel, UnboundedReceiver}; /// Routes calls to GattCallbacks into a channel of MockCallbackEvents diff --git a/system/rust/src/gatt/mocks/mock_database_callbacks.rs b/system/rust/src/gatt/mocks/mock_database_callbacks.rs index 991b2f5f04..38d13ae948 100644 --- a/system/rust/src/gatt/mocks/mock_database_callbacks.rs +++ b/system/rust/src/gatt/mocks/mock_database_callbacks.rs @@ -2,16 +2,10 @@ use std::ops::RangeInclusive; -use crate::{ - core::shared_box::{WeakBox, WeakBoxRef}, - gatt::{ - ids::{AttHandle, TransportIndex}, - server::{ - att_server_bearer::AttServerBearer, - gatt_database::{AttDatabaseImpl, GattDatabaseCallbacks}, - }, - }, -}; +use crate::core::shared_box::{WeakBox, WeakBoxRef}; +use crate::gatt::ids::{AttHandle, TransportIndex}; +use crate::gatt::server::att_server_bearer::AttServerBearer; +use crate::gatt::server::gatt_database::{AttDatabaseImpl, GattDatabaseCallbacks}; use tokio::sync::mpsc::{self, unbounded_channel, UnboundedReceiver}; /// Routes calls to GattDatabaseCallbacks into a channel of MockCallbackEvents diff --git a/system/rust/src/gatt/mocks/mock_datastore.rs b/system/rust/src/gatt/mocks/mock_datastore.rs index 0e024efd91..852ee69ddd 100644 --- a/system/rust/src/gatt/mocks/mock_datastore.rs +++ b/system/rust/src/gatt/mocks/mock_datastore.rs @@ -1,19 +1,13 @@ //! Mocked implementation of GattDatastore for use in test -use crate::{ - gatt::{ - callbacks::GattDatastore, - ffi::AttributeBackingType, - ids::{AttHandle, TransportIndex}, - }, - packets::att::AttErrorCode, -}; +use crate::gatt::callbacks::GattDatastore; +use crate::gatt::ffi::AttributeBackingType; +use crate::gatt::ids::{AttHandle, TransportIndex}; +use crate::packets::att::AttErrorCode; use async_trait::async_trait; use log::info; -use tokio::sync::{ - mpsc::{self, unbounded_channel, UnboundedReceiver}, - oneshot, -}; +use tokio::sync::mpsc::{self, unbounded_channel, UnboundedReceiver}; +use tokio::sync::oneshot; /// Routes calls to GattDatastore into a channel of MockDatastoreEvents pub struct MockDatastore(mpsc::UnboundedSender<MockDatastoreEvents>); diff --git a/system/rust/src/gatt/mocks/mock_raw_datastore.rs b/system/rust/src/gatt/mocks/mock_raw_datastore.rs index c43b47d586..28dc3e202d 100644 --- a/system/rust/src/gatt/mocks/mock_raw_datastore.rs +++ b/system/rust/src/gatt/mocks/mock_raw_datastore.rs @@ -1,19 +1,13 @@ //! Mocked implementation of GattDatastore for use in test -use crate::{ - gatt::{ - callbacks::{GattWriteRequestType, RawGattDatastore, TransactionDecision}, - ffi::AttributeBackingType, - ids::{AttHandle, TransportIndex}, - }, - packets::att::AttErrorCode, -}; +use crate::gatt::callbacks::{GattWriteRequestType, RawGattDatastore, TransactionDecision}; +use crate::gatt::ffi::AttributeBackingType; +use crate::gatt::ids::{AttHandle, TransportIndex}; +use crate::packets::att::AttErrorCode; use async_trait::async_trait; use log::info; -use tokio::sync::{ - mpsc::{self, unbounded_channel, UnboundedReceiver}, - oneshot, -}; +use tokio::sync::mpsc::{self, unbounded_channel, UnboundedReceiver}; +use tokio::sync::oneshot; /// Routes calls to RawGattDatastore into a channel of MockRawDatastoreEvents pub struct MockRawDatastore(mpsc::UnboundedSender<MockRawDatastoreEvents>); diff --git a/system/rust/src/gatt/mocks/mock_transport.rs b/system/rust/src/gatt/mocks/mock_transport.rs index 4db740c71a..cfccf4a125 100644 --- a/system/rust/src/gatt/mocks/mock_transport.rs +++ b/system/rust/src/gatt/mocks/mock_transport.rs @@ -1,11 +1,9 @@ //! Mocked implementation of AttTransport for use in test -use crate::{ - gatt::{channel::AttTransport, ids::TransportIndex}, - packets::att, -}; -use pdl_runtime::EncodeError; -use pdl_runtime::Packet; +use crate::gatt::channel::AttTransport; +use crate::gatt::ids::TransportIndex; +use crate::packets::att; +use pdl_runtime::{EncodeError, Packet}; use tokio::sync::mpsc::{self, unbounded_channel, UnboundedReceiver}; /// Routes calls to AttTransport into a channel containing AttBuilders diff --git a/system/rust/src/gatt/mtu.rs b/system/rust/src/gatt/mtu.rs index 3e7eaa4dbe..09c9d64c33 100644 --- a/system/rust/src/gatt/mtu.rs +++ b/system/rust/src/gatt/mtu.rs @@ -5,7 +5,8 @@ //! set. If the MTU is pending, ATT notifications/indications may not be sent. //! Refer to Core Spec 5.3 Vol 3F 3.4.2 MTU exchange for full details. -use std::{cell::Cell, future::Future}; +use std::cell::Cell; +use std::future::Future; use anyhow::{bail, Result}; use log::info; diff --git a/system/rust/src/gatt/server.rs b/system/rust/src/gatt/server.rs index c75be163aa..b7769f19dc 100644 --- a/system/rust/src/gatt/server.rs +++ b/system/rust/src/gatt/server.rs @@ -14,30 +14,22 @@ pub mod isolation_manager; #[cfg(test)] mod test; -use std::{ - collections::HashMap, - rc::Rc, - sync::{Arc, Mutex, MutexGuard}, -}; - -use crate::{ - core::shared_box::{SharedBox, WeakBox, WeakBoxRef}, - gatt::server::gatt_database::GattDatabase, -}; - -use self::{ - super::ids::ServerId, - att_server_bearer::AttServerBearer, - gatt_database::{AttDatabaseImpl, GattServiceWithHandle}, - isolation_manager::IsolationManager, - services::register_builtin_services, -}; - -use super::{ - callbacks::RawGattDatastore, - channel::AttTransport, - ids::{AdvertiserId, AttHandle, TransportIndex}, -}; +use std::collections::HashMap; +use std::rc::Rc; +use std::sync::{Arc, Mutex, MutexGuard}; + +use crate::core::shared_box::{SharedBox, WeakBox, WeakBoxRef}; +use crate::gatt::server::gatt_database::GattDatabase; + +use self::super::ids::ServerId; +use self::att_server_bearer::AttServerBearer; +use self::gatt_database::{AttDatabaseImpl, GattServiceWithHandle}; +use self::isolation_manager::IsolationManager; +use self::services::register_builtin_services; + +use super::callbacks::RawGattDatastore; +use super::channel::AttTransport; +use super::ids::{AdvertiserId, AttHandle, TransportIndex}; use anyhow::{anyhow, bail, Result}; use log::info; diff --git a/system/rust/src/gatt/server/att_database.rs b/system/rust/src/gatt/server/att_database.rs index cd322c6f8c..bc171a8ac9 100644 --- a/system/rust/src/gatt/server/att_database.rs +++ b/system/rust/src/gatt/server/att_database.rs @@ -1,11 +1,9 @@ use async_trait::async_trait; use bitflags::bitflags; -use crate::{ - core::uuid::Uuid, - gatt::ids::AttHandle, - packets::att::{self, AttErrorCode}, -}; +use crate::core::uuid::Uuid; +use crate::gatt::ids::AttHandle; +use crate::packets::att::{self, AttErrorCode}; impl From<att::AttHandle> for AttHandle { fn from(value: att::AttHandle) -> Self { diff --git a/system/rust/src/gatt/server/att_server_bearer.rs b/system/rust/src/gatt/server/att_server_bearer.rs index 0d78ad1278..8ec140da14 100644 --- a/system/rust/src/gatt/server/att_server_bearer.rs +++ b/system/rust/src/gatt/server/att_server_bearer.rs @@ -3,32 +3,25 @@ //! AttDatabase (that may in turn be backed by an upper-layer protocol) use pdl_runtime::EncodeError; -use std::{cell::Cell, future::Future}; +use std::cell::Cell; +use std::future::Future; use anyhow::Result; use log::{error, trace, warn}; use tokio::task::spawn_local; -use crate::{ - core::{ - shared_box::{WeakBox, WeakBoxRef}, - shared_mutex::SharedMutex, - }, - gatt::{ - ids::AttHandle, - mtu::{AttMtu, MtuEvent}, - opcode_types::{classify_opcode, OperationType}, - }, - packets::att::{self, AttErrorCode}, - utils::owned_handle::OwnedHandle, -}; - -use super::{ - att_database::AttDatabase, - command_handler::AttCommandHandler, - indication_handler::{ConfirmationWatcher, IndicationError, IndicationHandler}, - request_handler::AttRequestHandler, -}; +use crate::core::shared_box::{WeakBox, WeakBoxRef}; +use crate::core::shared_mutex::SharedMutex; +use crate::gatt::ids::AttHandle; +use crate::gatt::mtu::{AttMtu, MtuEvent}; +use crate::gatt::opcode_types::{classify_opcode, OperationType}; +use crate::packets::att::{self, AttErrorCode}; +use crate::utils::owned_handle::OwnedHandle; + +use super::att_database::AttDatabase; +use super::command_handler::AttCommandHandler; +use super::indication_handler::{ConfirmationWatcher, IndicationError, IndicationHandler}; +use super::request_handler::AttRequestHandler; enum AttRequestState<T: AttDatabase> { Idle(AttRequestHandler<T>), @@ -212,27 +205,23 @@ impl<T: AttDatabase + Clone + 'static> WeakBox<AttServerBearer<T>> { mod test { use std::rc::Rc; - use tokio::sync::mpsc::{error::TryRecvError, unbounded_channel, UnboundedReceiver}; + use tokio::sync::mpsc::error::TryRecvError; + use tokio::sync::mpsc::{unbounded_channel, UnboundedReceiver}; use super::*; - use crate::{ - core::{shared_box::SharedBox, uuid::Uuid}, - gatt::{ - ffi::AttributeBackingType, - ids::TransportIndex, - mocks::mock_datastore::{MockDatastore, MockDatastoreEvents}, - server::{ - att_database::{AttAttribute, AttPermissions}, - gatt_database::{ - GattCharacteristicWithHandle, GattDatabase, GattServiceWithHandle, - }, - test::test_att_db::TestAttDatabase, - }, - }, - packets::att, - utils::task::{block_on_locally, try_await}, + use crate::core::shared_box::SharedBox; + use crate::core::uuid::Uuid; + use crate::gatt::ffi::AttributeBackingType; + use crate::gatt::ids::TransportIndex; + use crate::gatt::mocks::mock_datastore::{MockDatastore, MockDatastoreEvents}; + use crate::gatt::server::att_database::{AttAttribute, AttPermissions}; + use crate::gatt::server::gatt_database::{ + GattCharacteristicWithHandle, GattDatabase, GattServiceWithHandle, }; + use crate::gatt::server::test::test_att_db::TestAttDatabase; + use crate::packets::att; + use crate::utils::task::{block_on_locally, try_await}; const VALID_HANDLE: AttHandle = AttHandle(3); const INVALID_HANDLE: AttHandle = AttHandle(4); diff --git a/system/rust/src/gatt/server/command_handler.rs b/system/rust/src/gatt/server/command_handler.rs index da54bb1ad8..8d9ac5afd9 100644 --- a/system/rust/src/gatt/server/command_handler.rs +++ b/system/rust/src/gatt/server/command_handler.rs @@ -33,20 +33,14 @@ impl<Db: AttDatabase> AttCommandHandler<Db> { #[cfg(test)] mod test { - use crate::{ - core::uuid::Uuid, - gatt::{ - ids::AttHandle, - server::{ - att_database::{AttAttribute, AttDatabase}, - command_handler::AttCommandHandler, - gatt_database::AttPermissions, - test::test_att_db::TestAttDatabase, - }, - }, - packets::att, - utils::task::block_on_locally, - }; + use crate::core::uuid::Uuid; + use crate::gatt::ids::AttHandle; + use crate::gatt::server::att_database::{AttAttribute, AttDatabase}; + use crate::gatt::server::command_handler::AttCommandHandler; + use crate::gatt::server::gatt_database::AttPermissions; + use crate::gatt::server::test::test_att_db::TestAttDatabase; + use crate::packets::att; + use crate::utils::task::block_on_locally; #[test] fn test_write_command() { diff --git a/system/rust/src/gatt/server/gatt_database.rs b/system/rust/src/gatt/server/gatt_database.rs index d1590b3866..2eaaeaa2ef 100644 --- a/system/rust/src/gatt/server/gatt_database.rs +++ b/system/rust/src/gatt/server/gatt_database.rs @@ -3,29 +3,24 @@ //! ATT read/write requests into characteristic reads/writes use pdl_runtime::Packet; -use std::{cell::RefCell, collections::BTreeMap, ops::RangeInclusive, rc::Rc}; +use std::cell::RefCell; +use std::collections::BTreeMap; +use std::ops::RangeInclusive; +use std::rc::Rc; use anyhow::{bail, Result}; use async_trait::async_trait; use log::{error, warn}; -use crate::{ - core::{ - shared_box::{SharedBox, WeakBox, WeakBoxRef}, - uuid::Uuid, - }, - gatt::{ - callbacks::{GattWriteRequestType, RawGattDatastore}, - ffi::AttributeBackingType, - ids::{AttHandle, TransportIndex}, - }, - packets::att::{self, AttErrorCode}, -}; - -use super::{ - att_database::{AttAttribute, AttDatabase}, - att_server_bearer::AttServerBearer, -}; +use crate::core::shared_box::{SharedBox, WeakBox, WeakBoxRef}; +use crate::core::uuid::Uuid; +use crate::gatt::callbacks::{GattWriteRequestType, RawGattDatastore}; +use crate::gatt::ffi::AttributeBackingType; +use crate::gatt::ids::{AttHandle, TransportIndex}; +use crate::packets::att::{self, AttErrorCode}; + +use super::att_database::{AttAttribute, AttDatabase}; +use super::att_server_bearer::AttServerBearer; pub use super::att_database::AttPermissions; @@ -510,17 +505,15 @@ impl AttDatabaseImpl { #[cfg(test)] mod test { - use tokio::{join, sync::mpsc::error::TryRecvError, task::spawn_local}; - - use crate::{ - gatt::mocks::{ - mock_database_callbacks::{MockCallbackEvents, MockCallbacks}, - mock_datastore::{MockDatastore, MockDatastoreEvents}, - mock_raw_datastore::{MockRawDatastore, MockRawDatastoreEvents}, - }, - packets::att, - utils::task::block_on_locally, - }; + use tokio::join; + use tokio::sync::mpsc::error::TryRecvError; + use tokio::task::spawn_local; + + use crate::gatt::mocks::mock_database_callbacks::{MockCallbackEvents, MockCallbacks}; + use crate::gatt::mocks::mock_datastore::{MockDatastore, MockDatastoreEvents}; + use crate::gatt::mocks::mock_raw_datastore::{MockRawDatastore, MockRawDatastoreEvents}; + use crate::packets::att; + use crate::utils::task::block_on_locally; use super::*; diff --git a/system/rust/src/gatt/server/indication_handler.rs b/system/rust/src/gatt/server/indication_handler.rs index 44ffe7ef27..4a0eb77654 100644 --- a/system/rust/src/gatt/server/indication_handler.rs +++ b/system/rust/src/gatt/server/indication_handler.rs @@ -1,17 +1,15 @@ use std::time::Duration; use log::{trace, warn}; -use tokio::{ - sync::mpsc::{self, error::TrySendError}, - time::timeout, -}; +use tokio::sync::mpsc::error::TrySendError; +use tokio::sync::mpsc::{self}; +use tokio::time::timeout; -use crate::{gatt::ids::AttHandle, packets::att}; +use crate::gatt::ids::AttHandle; +use crate::packets::att; -use super::{ - att_database::{AttDatabase, StableAttDatabase}, - att_server_bearer::SendError, -}; +use super::att_database::{AttDatabase, StableAttDatabase}; +use super::att_server_bearer::SendError; #[derive(Debug)] /// Errors that can occur while sending an indication @@ -116,16 +114,15 @@ impl ConfirmationWatcher { #[cfg(test)] mod test { use crate::packets::att; - use tokio::{sync::oneshot, task::spawn_local, time::Instant}; - - use crate::{ - core::uuid::Uuid, - gatt::server::{ - att_database::AttAttribute, gatt_database::AttPermissions, - test::test_att_db::TestAttDatabase, - }, - utils::task::block_on_locally, - }; + use tokio::sync::oneshot; + use tokio::task::spawn_local; + use tokio::time::Instant; + + use crate::core::uuid::Uuid; + use crate::gatt::server::att_database::AttAttribute; + use crate::gatt::server::gatt_database::AttPermissions; + use crate::gatt::server::test::test_att_db::TestAttDatabase; + use crate::utils::task::block_on_locally; use super::*; diff --git a/system/rust/src/gatt/server/request_handler.rs b/system/rust/src/gatt/server/request_handler.rs index a84bdfcea9..c6695ec7ae 100644 --- a/system/rust/src/gatt/server/request_handler.rs +++ b/system/rust/src/gatt/server/request_handler.rs @@ -1,22 +1,16 @@ use log::warn; -use pdl_runtime::DecodeError; -use pdl_runtime::EncodeError; - -use crate::{ - gatt::ids::AttHandle, - packets::att::{self, AttErrorCode}, -}; - -use super::{ - att_database::AttDatabase, - transactions::{ - find_by_type_value::handle_find_by_type_value_request, - find_information_request::handle_find_information_request, - read_by_group_type_request::handle_read_by_group_type_request, - read_by_type_request::handle_read_by_type_request, read_request::handle_read_request, - write_request::handle_write_request, - }, -}; +use pdl_runtime::{DecodeError, EncodeError}; + +use crate::gatt::ids::AttHandle; +use crate::packets::att::{self, AttErrorCode}; + +use super::att_database::AttDatabase; +use super::transactions::find_by_type_value::handle_find_by_type_value_request; +use super::transactions::find_information_request::handle_find_information_request; +use super::transactions::read_by_group_type_request::handle_read_by_group_type_request; +use super::transactions::read_by_type_request::handle_read_by_type_request; +use super::transactions::read_request::handle_read_request; +use super::transactions::write_request::handle_write_request; /// This struct handles all requests needing ACKs. Only ONE should exist per /// bearer per database, to ensure serialization. @@ -108,15 +102,11 @@ impl<Db: AttDatabase> AttRequestHandler<Db> { mod test { use super::*; - use crate::{ - core::uuid::Uuid, - gatt::server::{ - att_database::{AttAttribute, AttPermissions}, - request_handler::AttRequestHandler, - test::test_att_db::TestAttDatabase, - }, - packets::att, - }; + use crate::core::uuid::Uuid; + use crate::gatt::server::att_database::{AttAttribute, AttPermissions}; + use crate::gatt::server::request_handler::AttRequestHandler; + use crate::gatt::server::test::test_att_db::TestAttDatabase; + use crate::packets::att; #[test] fn test_read_request() { diff --git a/system/rust/src/gatt/server/services.rs b/system/rust/src/gatt/server/services.rs index a97db3a441..641bbc174a 100644 --- a/system/rust/src/gatt/server/services.rs +++ b/system/rust/src/gatt/server/services.rs @@ -6,7 +6,8 @@ pub mod gatt; use anyhow::Result; -use self::{gap::register_gap_service, gatt::register_gatt_service}; +use self::gap::register_gap_service; +use self::gatt::register_gatt_service; use super::gatt_database::GattDatabase; diff --git a/system/rust/src/gatt/server/services/gap.rs b/system/rust/src/gatt/server/services/gap.rs index 81853fa006..6402375954 100644 --- a/system/rust/src/gatt/server/services/gap.rs +++ b/system/rust/src/gatt/server/services/gap.rs @@ -5,18 +5,14 @@ use std::rc::Rc; use anyhow::Result; use async_trait::async_trait; -use crate::{ - core::uuid::Uuid, - gatt::{ - callbacks::GattDatastore, - ffi::AttributeBackingType, - ids::{AttHandle, TransportIndex}, - server::gatt_database::{ - AttPermissions, GattCharacteristicWithHandle, GattDatabase, GattServiceWithHandle, - }, - }, - packets::att::AttErrorCode, +use crate::core::uuid::Uuid; +use crate::gatt::callbacks::GattDatastore; +use crate::gatt::ffi::AttributeBackingType; +use crate::gatt::ids::{AttHandle, TransportIndex}; +use crate::gatt::server::gatt_database::{ + AttPermissions, GattCharacteristicWithHandle, GattDatabase, GattServiceWithHandle, }; +use crate::packets::att::AttErrorCode; struct GapService; @@ -95,14 +91,12 @@ pub fn register_gap_service(database: &mut GattDatabase) -> Result<()> { mod test { use super::*; - use crate::{ - core::shared_box::SharedBox, - gatt::server::{ - att_database::AttDatabase, - gatt_database::{GattDatabase, CHARACTERISTIC_UUID, PRIMARY_SERVICE_DECLARATION_UUID}, - }, - utils::task::block_on_locally, + use crate::core::shared_box::SharedBox; + use crate::gatt::server::att_database::AttDatabase; + use crate::gatt::server::gatt_database::{ + GattDatabase, CHARACTERISTIC_UUID, PRIMARY_SERVICE_DECLARATION_UUID, }; + use crate::utils::task::block_on_locally; const TCB_IDX: TransportIndex = TransportIndex(1); diff --git a/system/rust/src/gatt/server/services/gatt.rs b/system/rust/src/gatt/server/services/gatt.rs index 40514b4812..57cbe7c6b4 100644 --- a/system/rust/src/gatt/server/services/gatt.rs +++ b/system/rust/src/gatt/server/services/gatt.rs @@ -1,32 +1,27 @@ //! The GATT service as defined in Core Spec 5.3 Vol 3G Section 7 use pdl_runtime::Packet; -use std::{cell::RefCell, collections::HashMap, ops::RangeInclusive, rc::Rc}; +use std::cell::RefCell; +use std::collections::HashMap; +use std::ops::RangeInclusive; +use std::rc::Rc; use anyhow::Result; use async_trait::async_trait; use log::{error, warn}; use tokio::task::spawn_local; -use crate::{ - core::{ - shared_box::{WeakBox, WeakBoxRef}, - uuid::Uuid, - }, - gatt::{ - callbacks::GattDatastore, - ffi::AttributeBackingType, - ids::{AttHandle, TransportIndex}, - server::{ - att_server_bearer::AttServerBearer, - gatt_database::{ - AttDatabaseImpl, AttPermissions, GattCharacteristicWithHandle, GattDatabase, - GattDatabaseCallbacks, GattDescriptorWithHandle, GattServiceWithHandle, - }, - }, - }, - packets::att::{self, AttErrorCode}, +use crate::core::shared_box::{WeakBox, WeakBoxRef}; +use crate::core::uuid::Uuid; +use crate::gatt::callbacks::GattDatastore; +use crate::gatt::ffi::AttributeBackingType; +use crate::gatt::ids::{AttHandle, TransportIndex}; +use crate::gatt::server::att_server_bearer::AttServerBearer; +use crate::gatt::server::gatt_database::{ + AttDatabaseImpl, AttPermissions, GattCharacteristicWithHandle, GattDatabase, + GattDatabaseCallbacks, GattDescriptorWithHandle, GattServiceWithHandle, }; +use crate::packets::att::{self, AttErrorCode}; #[derive(Default)] struct GattService { @@ -178,20 +173,14 @@ mod test { use super::*; - use crate::{ - core::shared_box::SharedBox, - gatt::{ - mocks::mock_datastore::MockDatastore, - server::{ - att_database::AttDatabase, - gatt_database::{ - GattDatabase, CHARACTERISTIC_UUID, PRIMARY_SERVICE_DECLARATION_UUID, - }, - }, - }, - packets::att, - utils::task::{block_on_locally, try_await}, + use crate::core::shared_box::SharedBox; + use crate::gatt::mocks::mock_datastore::MockDatastore; + use crate::gatt::server::att_database::AttDatabase; + use crate::gatt::server::gatt_database::{ + GattDatabase, CHARACTERISTIC_UUID, PRIMARY_SERVICE_DECLARATION_UUID, }; + use crate::packets::att; + use crate::utils::task::{block_on_locally, try_await}; const TCB_IDX: TransportIndex = TransportIndex(1); const ANOTHER_TCB_IDX: TransportIndex = TransportIndex(2); diff --git a/system/rust/src/gatt/server/test/test_att_db.rs b/system/rust/src/gatt/server/test/test_att_db.rs index 64752f51cf..2011bafe64 100644 --- a/system/rust/src/gatt/server/test/test_att_db.rs +++ b/system/rust/src/gatt/server/test/test_att_db.rs @@ -1,14 +1,12 @@ -use crate::{ - gatt::{ - ids::AttHandle, - server::att_database::{AttAttribute, AttDatabase, StableAttDatabase}, - }, - packets::att::AttErrorCode, -}; +use crate::gatt::ids::AttHandle; +use crate::gatt::server::att_database::{AttAttribute, AttDatabase, StableAttDatabase}; +use crate::packets::att::AttErrorCode; use async_trait::async_trait; use log::{info, warn}; -use std::{cell::RefCell, collections::BTreeMap, rc::Rc}; +use std::cell::RefCell; +use std::collections::BTreeMap; +use std::rc::Rc; #[derive(Clone, Debug)] pub struct TestAttDatabase { diff --git a/system/rust/src/gatt/server/transactions/find_by_type_value.rs b/system/rust/src/gatt/server/transactions/find_by_type_value.rs index 382990f894..c967158db9 100644 --- a/system/rust/src/gatt/server/transactions/find_by_type_value.rs +++ b/system/rust/src/gatt/server/transactions/find_by_type_value.rs @@ -1,19 +1,14 @@ use log::warn; use pdl_runtime::EncodeError; -use crate::{ - core::uuid::Uuid, - gatt::{ - ids::AttHandle, - server::att_database::{AttAttribute, StableAttDatabase}, - }, - packets::att::{self, AttErrorCode}, -}; +use crate::core::uuid::Uuid; +use crate::gatt::ids::AttHandle; +use crate::gatt::server::att_database::{AttAttribute, StableAttDatabase}; +use crate::packets::att::{self, AttErrorCode}; -use super::helpers::{ - att_grouping::find_group_end, att_range_filter::filter_to_range, - payload_accumulator::PayloadAccumulator, -}; +use super::helpers::att_grouping::find_group_end; +use super::helpers::att_range_filter::filter_to_range; +use super::helpers::payload_accumulator::PayloadAccumulator; pub async fn handle_find_by_type_value_request( request: att::AttFindByTypeValueRequest, @@ -72,18 +67,12 @@ pub async fn handle_find_by_type_value_request( #[cfg(test)] mod test { - use crate::{ - gatt::{ - ffi::Uuid, - server::{ - gatt_database::{ - AttPermissions, CHARACTERISTIC_UUID, PRIMARY_SERVICE_DECLARATION_UUID, - }, - test::test_att_db::TestAttDatabase, - }, - }, - packets::att, + use crate::gatt::ffi::Uuid; + use crate::gatt::server::gatt_database::{ + AttPermissions, CHARACTERISTIC_UUID, PRIMARY_SERVICE_DECLARATION_UUID, }; + use crate::gatt::server::test::test_att_db::TestAttDatabase; + use crate::packets::att; use super::*; diff --git a/system/rust/src/gatt/server/transactions/find_information_request.rs b/system/rust/src/gatt/server/transactions/find_information_request.rs index e9079f3a1d..b33cacce69 100644 --- a/system/rust/src/gatt/server/transactions/find_information_request.rs +++ b/system/rust/src/gatt/server/transactions/find_information_request.rs @@ -1,10 +1,9 @@ -use crate::{ - gatt::server::att_database::{AttAttribute, AttDatabase}, - packets::att::{self, AttErrorCode}, -}; +use crate::gatt::server::att_database::{AttAttribute, AttDatabase}; +use crate::packets::att::{self, AttErrorCode}; use pdl_runtime::EncodeError; -use super::helpers::{att_range_filter::filter_to_range, payload_accumulator::PayloadAccumulator}; +use super::helpers::att_range_filter::filter_to_range; +use super::helpers::payload_accumulator::PayloadAccumulator; pub fn handle_find_information_request<T: AttDatabase>( request: att::AttFindInformationRequest, @@ -89,12 +88,11 @@ fn handle_find_information_request_long( #[cfg(test)] mod test { + use crate::core::uuid::Uuid; + use crate::gatt::server::gatt_database::AttPermissions; + use crate::gatt::server::test::test_att_db::TestAttDatabase; use crate::gatt::server::AttHandle; - use crate::{ - core::uuid::Uuid, - gatt::server::{gatt_database::AttPermissions, test::test_att_db::TestAttDatabase}, - packets::att, - }; + use crate::packets::att; use super::*; diff --git a/system/rust/src/gatt/server/transactions/helpers/att_filter_by_size_type.rs b/system/rust/src/gatt/server/transactions/helpers/att_filter_by_size_type.rs index 1674597bc4..1e8870c642 100644 --- a/system/rust/src/gatt/server/transactions/helpers/att_filter_by_size_type.rs +++ b/system/rust/src/gatt/server/transactions/helpers/att_filter_by_size_type.rs @@ -1,11 +1,9 @@ //! This module extracts the common logic in filtering attributes by type + //! length, used in READ_BY_TYPE_REQ and READ_BY_GROUP_TYPE_REQ -use crate::{ - core::uuid::Uuid, - gatt::server::att_database::{AttAttribute, StableAttDatabase}, - packets::att::AttErrorCode, -}; +use crate::core::uuid::Uuid; +use crate::gatt::server::att_database::{AttAttribute, StableAttDatabase}; +use crate::packets::att::AttErrorCode; /// An attribute and the value #[derive(Debug, PartialEq, Eq)] @@ -67,17 +65,11 @@ pub async fn filter_read_attributes_by_size_type( mod test { use super::*; - use crate::{ - core::uuid::Uuid, - gatt::{ - ids::AttHandle, - server::{ - att_database::{AttAttribute, AttDatabase, StableAttDatabase}, - gatt_database::AttPermissions, - test::test_att_db::TestAttDatabase, - }, - }, - }; + use crate::core::uuid::Uuid; + use crate::gatt::ids::AttHandle; + use crate::gatt::server::att_database::{AttAttribute, AttDatabase, StableAttDatabase}; + use crate::gatt::server::gatt_database::AttPermissions; + use crate::gatt::server::test::test_att_db::TestAttDatabase; const UUID: Uuid = Uuid::new(1234); const ANOTHER_UUID: Uuid = Uuid::new(2345); diff --git a/system/rust/src/gatt/server/transactions/helpers/att_grouping.rs b/system/rust/src/gatt/server/transactions/helpers/att_grouping.rs index fee52d7c60..1596475ac6 100644 --- a/system/rust/src/gatt/server/transactions/helpers/att_grouping.rs +++ b/system/rust/src/gatt/server/transactions/helpers/att_grouping.rs @@ -54,10 +54,9 @@ pub fn find_group_end( #[cfg(test)] mod test { - use crate::gatt::{ - ids::AttHandle, - server::{gatt_database::AttPermissions, test::test_att_db::TestAttDatabase}, - }; + use crate::gatt::ids::AttHandle; + use crate::gatt::server::gatt_database::AttPermissions; + use crate::gatt::server::test::test_att_db::TestAttDatabase; use super::*; diff --git a/system/rust/src/gatt/server/transactions/helpers/att_range_filter.rs b/system/rust/src/gatt/server/transactions/helpers/att_range_filter.rs index 70be91d6a6..b70119b0a4 100644 --- a/system/rust/src/gatt/server/transactions/helpers/att_range_filter.rs +++ b/system/rust/src/gatt/server/transactions/helpers/att_range_filter.rs @@ -2,7 +2,8 @@ //! in many ATT commands, such as ATT_FIND_INFORMATION_REQ and //! ATT_FIND_BY_TYPE_VALUE REQ -use crate::gatt::{ids::AttHandle, server::att_database::AttAttribute}; +use crate::gatt::ids::AttHandle; +use crate::gatt::server::att_database::AttAttribute; /// Filter a (sorted) iterator of attributes to those that lie within /// the specified range. If the range is invalid (start = 0, or start > end), @@ -24,7 +25,7 @@ pub fn filter_to_range( #[cfg(test)] mod test { - use crate::gatt::server::{gatt_database::AttPermissions, gatt_database::CHARACTERISTIC_UUID}; + use crate::gatt::server::gatt_database::{AttPermissions, CHARACTERISTIC_UUID}; use super::*; diff --git a/system/rust/src/gatt/server/transactions/read_by_group_type_request.rs b/system/rust/src/gatt/server/transactions/read_by_group_type_request.rs index 319d5e6c45..7bff62c72e 100644 --- a/system/rust/src/gatt/server/transactions/read_by_group_type_request.rs +++ b/system/rust/src/gatt/server/transactions/read_by_group_type_request.rs @@ -1,19 +1,17 @@ -use crate::{ - core::uuid::Uuid, - gatt::server::{ - att_database::StableAttDatabase, - gatt_database::{PRIMARY_SERVICE_DECLARATION_UUID, SECONDARY_SERVICE_DECLARATION_UUID}, - }, - packets::att::{self, AttErrorCode}, +use crate::core::uuid::Uuid; +use crate::gatt::server::att_database::StableAttDatabase; +use crate::gatt::server::gatt_database::{ + PRIMARY_SERVICE_DECLARATION_UUID, SECONDARY_SERVICE_DECLARATION_UUID, }; +use crate::packets::att::{self, AttErrorCode}; use pdl_runtime::EncodeError; -use super::helpers::{ - att_filter_by_size_type::{filter_read_attributes_by_size_type, AttributeWithValue}, - att_grouping::find_group_end, - att_range_filter::filter_to_range, - payload_accumulator::PayloadAccumulator, +use super::helpers::att_filter_by_size_type::{ + filter_read_attributes_by_size_type, AttributeWithValue, }; +use super::helpers::att_grouping::find_group_end; +use super::helpers::att_range_filter::filter_to_range; +use super::helpers::payload_accumulator::PayloadAccumulator; pub async fn handle_read_by_group_type_request( request: att::AttReadByGroupTypeRequest, @@ -92,17 +90,11 @@ pub async fn handle_read_by_group_type_request( #[cfg(test)] mod test { - use crate::{ - gatt::{ - ids::AttHandle, - server::{ - att_database::AttAttribute, - gatt_database::{AttPermissions, CHARACTERISTIC_UUID}, - test::test_att_db::TestAttDatabase, - }, - }, - packets::att, - }; + use crate::gatt::ids::AttHandle; + use crate::gatt::server::att_database::AttAttribute; + use crate::gatt::server::gatt_database::{AttPermissions, CHARACTERISTIC_UUID}; + use crate::gatt::server::test::test_att_db::TestAttDatabase; + use crate::packets::att; use super::*; diff --git a/system/rust/src/gatt/server/transactions/read_by_type_request.rs b/system/rust/src/gatt/server/transactions/read_by_type_request.rs index 3e7f3b44c4..eec8815ee8 100644 --- a/system/rust/src/gatt/server/transactions/read_by_type_request.rs +++ b/system/rust/src/gatt/server/transactions/read_by_type_request.rs @@ -1,15 +1,13 @@ -use crate::{ - core::uuid::Uuid, - gatt::server::att_database::StableAttDatabase, - packets::att::{self, AttErrorCode}, -}; +use crate::core::uuid::Uuid; +use crate::gatt::server::att_database::StableAttDatabase; +use crate::packets::att::{self, AttErrorCode}; use pdl_runtime::EncodeError; -use super::helpers::{ - att_filter_by_size_type::{filter_read_attributes_by_size_type, AttributeWithValue}, - att_range_filter::filter_to_range, - payload_accumulator::PayloadAccumulator, +use super::helpers::att_filter_by_size_type::{ + filter_read_attributes_by_size_type, AttributeWithValue, }; +use super::helpers::att_range_filter::filter_to_range; +use super::helpers::payload_accumulator::PayloadAccumulator; pub async fn handle_read_by_type_request( request: att::AttReadByTypeRequest, @@ -74,17 +72,12 @@ pub async fn handle_read_by_type_request( mod test { use super::*; - use crate::{ - core::uuid::Uuid, - gatt::{ - ids::AttHandle, - server::{ - att_database::AttAttribute, gatt_database::AttPermissions, - test::test_att_db::TestAttDatabase, - }, - }, - packets::att, - }; + use crate::core::uuid::Uuid; + use crate::gatt::ids::AttHandle; + use crate::gatt::server::att_database::AttAttribute; + use crate::gatt::server::gatt_database::AttPermissions; + use crate::gatt::server::test::test_att_db::TestAttDatabase; + use crate::packets::att; const UUID: Uuid = Uuid::new(1234); const ANOTHER_UUID: Uuid = Uuid::new(2345); diff --git a/system/rust/src/gatt/server/transactions/read_request.rs b/system/rust/src/gatt/server/transactions/read_request.rs index b5827deeb5..17cb6e8e83 100644 --- a/system/rust/src/gatt/server/transactions/read_request.rs +++ b/system/rust/src/gatt/server/transactions/read_request.rs @@ -1,4 +1,5 @@ -use crate::{gatt::server::att_database::AttDatabase, packets::att}; +use crate::gatt::server::att_database::AttDatabase; +use crate::packets::att; use pdl_runtime::EncodeError; pub async fn handle_read_request<T: AttDatabase>( @@ -27,17 +28,11 @@ pub async fn handle_read_request<T: AttDatabase>( mod test { use super::*; - use crate::{ - core::uuid::Uuid, - gatt::{ - ids::AttHandle, - server::{ - att_database::{AttAttribute, AttPermissions}, - test::test_att_db::TestAttDatabase, - }, - }, - packets::att, - }; + use crate::core::uuid::Uuid; + use crate::gatt::ids::AttHandle; + use crate::gatt::server::att_database::{AttAttribute, AttPermissions}; + use crate::gatt::server::test::test_att_db::TestAttDatabase; + use crate::packets::att; fn make_db_with_handle_and_value(handle: u16, value: Vec<u8>) -> TestAttDatabase { TestAttDatabase::new(vec![( diff --git a/system/rust/src/gatt/server/transactions/write_request.rs b/system/rust/src/gatt/server/transactions/write_request.rs index 226d57fc98..f3a41e6937 100644 --- a/system/rust/src/gatt/server/transactions/write_request.rs +++ b/system/rust/src/gatt/server/transactions/write_request.rs @@ -1,4 +1,5 @@ -use crate::{gatt::server::att_database::AttDatabase, packets::att}; +use crate::gatt::server::att_database::AttDatabase; +use crate::packets::att; use pdl_runtime::EncodeError; pub async fn handle_write_request<T: AttDatabase>( @@ -24,18 +25,12 @@ mod test { use tokio_test::block_on; - use crate::{ - core::uuid::Uuid, - gatt::{ - ids::AttHandle, - server::{ - att_database::{AttAttribute, AttDatabase}, - gatt_database::AttPermissions, - test::test_att_db::TestAttDatabase, - }, - }, - packets::att, - }; + use crate::core::uuid::Uuid; + use crate::gatt::ids::AttHandle; + use crate::gatt::server::att_database::{AttAttribute, AttDatabase}; + use crate::gatt::server::gatt_database::AttPermissions; + use crate::gatt::server::test::test_att_db::TestAttDatabase; + use crate::packets::att; #[test] fn test_successful_write() { diff --git a/system/rust/src/lib.rs b/system/rust/src/lib.rs index 3886ee4772..f88e635911 100644 --- a/system/rust/src/lib.rs +++ b/system/rust/src/lib.rs @@ -15,11 +15,14 @@ //! The core event loop for Rust modules. Here Rust modules are started in //! dependency order. -use gatt::{channel::AttTransport, GattCallbacks}; +use gatt::channel::AttTransport; +use gatt::GattCallbacks; use log::{info, warn}; use tokio::task::LocalSet; -use std::{rc::Rc, sync::Mutex, thread::JoinHandle}; +use std::rc::Rc; +use std::sync::Mutex; +use std::thread::JoinHandle; use tokio::runtime::Builder; use tokio::sync::mpsc; diff --git a/system/rust/src/utils/task.rs b/system/rust/src/utils/task.rs index 4e2753be7c..087f714260 100644 --- a/system/rust/src/utils/task.rs +++ b/system/rust/src/utils/task.rs @@ -1,16 +1,12 @@ //! This module provides utilities relating to async tasks, typically for usage //! only in test -use std::{ - future::{Future, IntoFuture}, - time::Duration, -}; +use std::future::{Future, IntoFuture}; +use std::time::Duration; -use tokio::{ - runtime::Builder, - select, - task::{spawn_local, LocalSet}, -}; +use tokio::runtime::Builder; +use tokio::select; +use tokio::task::{spawn_local, LocalSet}; /// Run the supplied future on a single-threaded runtime pub fn block_on_locally<T>(f: impl Future<Output = T>) -> T { diff --git a/system/rust/tests/gatt_callbacks_test.rs b/system/rust/tests/gatt_callbacks_test.rs index 84409f376e..8bb1c37bdd 100644 --- a/system/rust/tests/gatt_callbacks_test.rs +++ b/system/rust/tests/gatt_callbacks_test.rs @@ -1,20 +1,19 @@ mod utils; -use std::{rc::Rc, time::Duration}; - -use bluetooth_core::{ - gatt::{ - callbacks::{ - CallbackResponseError, CallbackTransactionManager, GattWriteRequestType, GattWriteType, - RawGattDatastore, TransactionDecision, - }, - ffi::AttributeBackingType, - ids::{AttHandle, ConnectionId, ServerId, TransactionId, TransportIndex}, - mocks::mock_callbacks::{MockCallbackEvents, MockCallbacks}, - }, - packets::att::AttErrorCode, +use std::rc::Rc; +use std::time::Duration; + +use bluetooth_core::gatt::callbacks::{ + CallbackResponseError, CallbackTransactionManager, GattWriteRequestType, GattWriteType, + RawGattDatastore, TransactionDecision, }; -use tokio::{sync::mpsc::UnboundedReceiver, task::spawn_local, time::Instant}; +use bluetooth_core::gatt::ffi::AttributeBackingType; +use bluetooth_core::gatt::ids::{AttHandle, ConnectionId, ServerId, TransactionId, TransportIndex}; +use bluetooth_core::gatt::mocks::mock_callbacks::{MockCallbackEvents, MockCallbacks}; +use bluetooth_core::packets::att::AttErrorCode; +use tokio::sync::mpsc::UnboundedReceiver; +use tokio::task::spawn_local; +use tokio::time::Instant; use utils::start_test; const TCB_IDX: TransportIndex = TransportIndex(1); diff --git a/system/rust/tests/gatt_server_test.rs b/system/rust/tests/gatt_server_test.rs index cf91d35ad8..2f14f0b4cb 100644 --- a/system/rust/tests/gatt_server_test.rs +++ b/system/rust/tests/gatt_server_test.rs @@ -1,42 +1,28 @@ use pdl_runtime::Packet; -use std::{ - rc::Rc, - sync::{Arc, Mutex}, +use std::rc::Rc; +use std::sync::{Arc, Mutex}; + +use bluetooth_core::core::uuid::Uuid; +use bluetooth_core::gatt::ffi::AttributeBackingType; +use bluetooth_core::gatt::ids::{AdvertiserId, AttHandle, ServerId, TransportIndex}; +use bluetooth_core::gatt::mocks::mock_datastore::{MockDatastore, MockDatastoreEvents}; +use bluetooth_core::gatt::mocks::mock_transport::MockAttTransport; +use bluetooth_core::gatt::server::gatt_database::{ + AttPermissions, GattCharacteristicWithHandle, GattDescriptorWithHandle, GattServiceWithHandle, + CHARACTERISTIC_UUID, PRIMARY_SERVICE_DECLARATION_UUID, }; - -use bluetooth_core::{ - core::uuid::Uuid, - gatt::{ - self, - ffi::AttributeBackingType, - ids::{AdvertiserId, AttHandle, ServerId, TransportIndex}, - mocks::{ - mock_datastore::{MockDatastore, MockDatastoreEvents}, - mock_transport::MockAttTransport, - }, - server::{ - gatt_database::{ - AttPermissions, GattCharacteristicWithHandle, GattDescriptorWithHandle, - GattServiceWithHandle, CHARACTERISTIC_UUID, PRIMARY_SERVICE_DECLARATION_UUID, - }, - isolation_manager::IsolationManager, - services::{ - gap::DEVICE_NAME_UUID, - gatt::{ - CLIENT_CHARACTERISTIC_CONFIGURATION_UUID, GATT_SERVICE_UUID, - SERVICE_CHANGE_UUID, - }, - }, - GattModule, IndicationError, - }, - }, - packets::att::{self, AttErrorCode}, +use bluetooth_core::gatt::server::isolation_manager::IsolationManager; +use bluetooth_core::gatt::server::services::gap::DEVICE_NAME_UUID; +use bluetooth_core::gatt::server::services::gatt::{ + CLIENT_CHARACTERISTIC_CONFIGURATION_UUID, GATT_SERVICE_UUID, SERVICE_CHANGE_UUID, }; +use bluetooth_core::gatt::server::{GattModule, IndicationError}; +use bluetooth_core::gatt::{self}; +use bluetooth_core::packets::att::{self, AttErrorCode}; -use tokio::{ - sync::mpsc::{error::TryRecvError, UnboundedReceiver}, - task::spawn_local, -}; +use tokio::sync::mpsc::error::TryRecvError; +use tokio::sync::mpsc::UnboundedReceiver; +use tokio::task::spawn_local; use utils::start_test; mod utils; diff --git a/system/stack/btm/btm_ble_gap.cc b/system/stack/btm/btm_ble_gap.cc index 92a9420341..b399c1edaf 100644 --- a/system/stack/btm/btm_ble_gap.cc +++ b/system/stack/btm/btm_ble_gap.cc @@ -37,6 +37,7 @@ #include <type_traits> #include <vector> +#include "ble_appearance.h" #include "bta/include/bta_api.h" #include "common/time_util.h" #include "hci/controller.h" @@ -1801,139 +1802,18 @@ static uint8_t btm_ble_is_discoverable(const RawAddress& /* bda */, return scan_state; } +/** + * Converts BLE appearance value to Class of Device + * Note: To add mapping for a new BLE appearance value for a category, add the + * mapping under the appropriate APPEARANCE_TO_COD_XXXX macro. + */ static DEV_CLASS btm_ble_appearance_to_cod(uint16_t appearance) { - DEV_CLASS dev_class = kDevClassEmpty; - switch (appearance) { - case BTM_BLE_APPEARANCE_GENERIC_PHONE: - dev_class[1] = BTM_COD_MAJOR_PHONE; - dev_class[2] = BTM_COD_MINOR_UNCLASSIFIED; - break; - case BTM_BLE_APPEARANCE_GENERIC_COMPUTER: - dev_class[1] = BTM_COD_MAJOR_COMPUTER; - dev_class[2] = BTM_COD_MINOR_UNCLASSIFIED; - break; - case BTM_BLE_APPEARANCE_GENERIC_REMOTE: - dev_class[1] = BTM_COD_MAJOR_PERIPHERAL; - dev_class[2] = BTM_COD_MINOR_REMOTE_CONTROL; - break; - case BTM_BLE_APPEARANCE_GENERIC_THERMOMETER: - case BTM_BLE_APPEARANCE_THERMOMETER_EAR: - dev_class[1] = BTM_COD_MAJOR_HEALTH; - dev_class[2] = BTM_COD_MINOR_THERMOMETER; - break; - case BTM_BLE_APPEARANCE_GENERIC_HEART_RATE: - case BTM_BLE_APPEARANCE_HEART_RATE_BELT: - dev_class[1] = BTM_COD_MAJOR_HEALTH; - dev_class[2] = BTM_COD_MINOR_HEART_PULSE_MONITOR; - break; - case BTM_BLE_APPEARANCE_GENERIC_BLOOD_PRESSURE: - case BTM_BLE_APPEARANCE_BLOOD_PRESSURE_ARM: - case BTM_BLE_APPEARANCE_BLOOD_PRESSURE_WRIST: - dev_class[1] = BTM_COD_MAJOR_HEALTH; - dev_class[2] = BTM_COD_MINOR_BLOOD_MONITOR; - break; - case BTM_BLE_APPEARANCE_GENERIC_PULSE_OXIMETER: - case BTM_BLE_APPEARANCE_PULSE_OXIMETER_FINGERTIP: - case BTM_BLE_APPEARANCE_PULSE_OXIMETER_WRIST: - dev_class[1] = BTM_COD_MAJOR_HEALTH; - dev_class[2] = BTM_COD_MINOR_PULSE_OXIMETER; - break; - case BTM_BLE_APPEARANCE_GENERIC_GLUCOSE: - dev_class[1] = BTM_COD_MAJOR_HEALTH; - dev_class[2] = BTM_COD_MINOR_GLUCOSE_METER; - break; - case BTM_BLE_APPEARANCE_GENERIC_WEIGHT: - dev_class[1] = BTM_COD_MAJOR_HEALTH; - dev_class[2] = BTM_COD_MINOR_WEIGHING_SCALE; - break; - case BTM_BLE_APPEARANCE_GENERIC_WALKING: - case BTM_BLE_APPEARANCE_WALKING_IN_SHOE: - case BTM_BLE_APPEARANCE_WALKING_ON_SHOE: - case BTM_BLE_APPEARANCE_WALKING_ON_HIP: - dev_class[1] = BTM_COD_MAJOR_HEALTH; - dev_class[2] = BTM_COD_MINOR_STEP_COUNTER; - break; - case BTM_BLE_APPEARANCE_GENERIC_WATCH: - case BTM_BLE_APPEARANCE_SPORTS_WATCH: - dev_class[1] = BTM_COD_MAJOR_WEARABLE; - dev_class[2] = BTM_COD_MINOR_WRIST_WATCH; - break; - case BTM_BLE_APPEARANCE_GENERIC_EYEGLASSES: - dev_class[1] = BTM_COD_MAJOR_WEARABLE; - dev_class[2] = BTM_COD_MINOR_GLASSES; - break; - case BTM_BLE_APPEARANCE_GENERIC_DISPLAY: - dev_class[1] = BTM_COD_MAJOR_IMAGING; - dev_class[2] = BTM_COD_MINOR_DISPLAY; - break; - case BTM_BLE_APPEARANCE_GENERIC_MEDIA_PLAYER: - dev_class[1] = BTM_COD_MAJOR_AUDIO; - dev_class[2] = BTM_COD_MINOR_UNCLASSIFIED; - break; - case BTM_BLE_APPEARANCE_GENERIC_WEARABLE_AUDIO_DEVICE: - case BTM_BLE_APPEARANCE_WEARABLE_AUDIO_DEVICE_EARBUD: - case BTM_BLE_APPEARANCE_WEARABLE_AUDIO_DEVICE_HEADSET: - case BTM_BLE_APPEARANCE_WEARABLE_AUDIO_DEVICE_HEADPHONES: - case BTM_BLE_APPEARANCE_WEARABLE_AUDIO_DEVICE_NECK_BAND: - dev_class[0] = (BTM_COD_SERVICE_AUDIO | BTM_COD_SERVICE_RENDERING) >> 8; - dev_class[1] = (BTM_COD_MAJOR_AUDIO | BTM_COD_SERVICE_LE_AUDIO); - dev_class[2] = BTM_COD_MINOR_WEARABLE_HEADSET; - break; - case BTM_BLE_APPEARANCE_GENERIC_BARCODE_SCANNER: - case BTM_BLE_APPEARANCE_HID_BARCODE_SCANNER: - case BTM_BLE_APPEARANCE_GENERIC_HID: - dev_class[1] = BTM_COD_MAJOR_PERIPHERAL; - dev_class[2] = BTM_COD_MINOR_UNCLASSIFIED; - break; - case BTM_BLE_APPEARANCE_HID_KEYBOARD: - dev_class[1] = BTM_COD_MAJOR_PERIPHERAL; - dev_class[2] = BTM_COD_MINOR_KEYBOARD; - break; - case BTM_BLE_APPEARANCE_HID_MOUSE: - dev_class[1] = BTM_COD_MAJOR_PERIPHERAL; - dev_class[2] = BTM_COD_MINOR_POINTING; - break; - case BTM_BLE_APPEARANCE_HID_JOYSTICK: - dev_class[1] = BTM_COD_MAJOR_PERIPHERAL; - dev_class[2] = BTM_COD_MINOR_JOYSTICK; - break; - case BTM_BLE_APPEARANCE_HID_GAMEPAD: - dev_class[1] = BTM_COD_MAJOR_PERIPHERAL; - dev_class[2] = BTM_COD_MINOR_GAMEPAD; - break; - case BTM_BLE_APPEARANCE_HID_DIGITIZER_TABLET: - dev_class[1] = BTM_COD_MAJOR_PERIPHERAL; - dev_class[2] = BTM_COD_MINOR_DIGITIZING_TABLET; - break; - case BTM_BLE_APPEARANCE_HID_CARD_READER: - dev_class[1] = BTM_COD_MAJOR_PERIPHERAL; - dev_class[2] = BTM_COD_MINOR_CARD_READER; - break; - case BTM_BLE_APPEARANCE_HID_DIGITAL_PEN: - dev_class[1] = BTM_COD_MAJOR_PERIPHERAL; - dev_class[2] = BTM_COD_MINOR_DIGITAL_PAN; - break; - case BTM_BLE_APPEARANCE_UNKNOWN: - case BTM_BLE_APPEARANCE_GENERIC_CLOCK: - case BTM_BLE_APPEARANCE_GENERIC_TAG: - case BTM_BLE_APPEARANCE_GENERIC_KEYRING: - case BTM_BLE_APPEARANCE_GENERIC_CYCLING: - case BTM_BLE_APPEARANCE_CYCLING_COMPUTER: - case BTM_BLE_APPEARANCE_CYCLING_SPEED: - case BTM_BLE_APPEARANCE_CYCLING_CADENCE: - case BTM_BLE_APPEARANCE_CYCLING_POWER: - case BTM_BLE_APPEARANCE_CYCLING_SPEED_CADENCE: - case BTM_BLE_APPEARANCE_GENERIC_OUTDOOR_SPORTS: - case BTM_BLE_APPEARANCE_OUTDOOR_SPORTS_LOCATION: - case BTM_BLE_APPEARANCE_OUTDOOR_SPORTS_LOCATION_AND_NAV: - case BTM_BLE_APPEARANCE_OUTDOOR_SPORTS_LOCATION_POD: - case BTM_BLE_APPEARANCE_OUTDOOR_SPORTS_LOCATION_POD_AND_NAV: - default: - dev_class[1] = BTM_COD_MAJOR_UNCLASSIFIED; - dev_class[2] = BTM_COD_MINOR_UNCLASSIFIED; + APPEARANCE_TO_COD(ADD_APPEARANCE_TO_COD_CASE); + // No need of adding default case }; - return dev_class; + + return kDevClassEmpty; } DEV_CLASS btm_ble_get_appearance_as_cod(std::vector<uint8_t> const& data) { diff --git a/system/stack/include/ble_appearance.h b/system/stack/include/ble_appearance.h index 6dbb32996c..eb20c91b0f 100644 --- a/system/stack/include/ble_appearance.h +++ b/system/stack/include/ble_appearance.h @@ -19,16 +19,36 @@ #ifndef BLE_APPEARANCE_H #define BLE_APPEARANCE_H -/* BLE appearance values as per BT spec assigned numbers */ -/* Category[15:6] 0x000 */ -#define BLE_APPEARANCE_UNKNOWN 0x0000 - -/* Category[15:6] 0x001 */ -#define BLE_APPEARANCE_GENERIC_PHONE 0x0040 - -/* Category[15:6] 0x002 */ -#define BLE_APPEARANCE_GENERIC_COMPUTER 0x0080 - +#include <cstdint> + +#include "bt_dev_class.h" + +/** + * BLE appearance values as per BT spec assigned numbers. + * Definitions and mapping from BLE appearance to COD. + * The set represents: + * - BLE Appearance string + * - BLE Appearance value + * - Class of device Service + * - COD Major Class + * - COD Minor Class + * + * Note: To add mapping for a new BLE appearance value for a category, add a + * new macro to the appropriate APPEARANCE_TO_COD_XXXX macro, and then + * add this APPEARANCE_TO_COD_XXXX macro to the APPEARANCE_TO_COD macro + * (if not already added). + */ + +/* Category Unknown [15:6] 0x000 */ +#define APPEARANCE_TO_COD_UNKNOWN(X) \ + X(BLE_APPEARANCE_UNKNOWN, 0x0000, COD_SERVICE_NA, COD_MAJOR_UNCLASSIFIED, COD_MINOR_UNCATEGORIZED) + +/* Category Phone [15:6] 0x001 */ +#define APPEARANCE_TO_COD_PHONE(X) \ + X(BLE_APPEARANCE_GENERIC_PHONE, 0x0040, COD_SERVICE_NA, COD_MAJOR_PHONE, \ + COD_MAJOR_PHONE_MINOR_UNCATEGORIZED) + +/* Category Computer [15:6] 0x002 */ #define BLE_APPEARANCE_DESKTOP_WORKSTATION 0x81 #define BLE_APPEARANCE_SERVER_CLASS_COMPUTER 0x82 #define BLE_APPEARANCE_LAPTOP 0x83 @@ -44,72 +64,115 @@ #define BLE_APPEARANCE_IOT_GATEWAY 0x8D #define BLE_APPEARANCE_MINI_PC 0x8E #define BLE_APPEARANCE_STICK_PC 0x8F +#define APPEARANCE_TO_COD_COMPUTER(X) \ + X(BLE_APPEARANCE_GENERIC_COMPUTER, 0x0080, COD_SERVICE_NA, COD_MAJOR_COMPUTER, \ + COD_MAJOR_COMPUTER_MINOR_UNCATEGORIZED) -/* Category[15:6] 0x003 */ -#define BLE_APPEARANCE_GENERIC_WATCH 0x00C0 -#define BLE_APPEARANCE_SPORTS_WATCH 0x00C1 +/* Category Watch [15:6] 0x003 */ #define BLE_APPEARANCE_SMART_WATCH 0x00C2 +#define APPEARANCE_TO_COD_WATCH(X) \ + X(BLE_APPEARANCE_GENERIC_WATCH, 0x00C0, COD_SERVICE_NA, COD_MAJOR_WEARABLE, \ + COD_MAJOR_WEARABLE_MINOR_WRIST_WATCH) \ + X(BLE_APPEARANCE_SPORTS_WATCH, 0x00C1, COD_SERVICE_NA, COD_MAJOR_WEARABLE, \ + COD_MAJOR_WEARABLE_MINOR_WRIST_WATCH) -/* Category[15:6] 0x004 */ +/* Category Clock [15:6] 0x004 */ #define BLE_APPEARANCE_GENERIC_CLOCK 0x0100 -/* Category[15:6] 0x005 */ -#define BLE_APPEARANCE_GENERIC_DISPLAY 0x0140 +/* Category Display [15:6] 0x005 */ +#define APPEARANCE_TO_COD_DISPLAY(X) \ + X(BLE_APPEARANCE_GENERIC_DISPLAY, 0x0140, COD_SERVICE_NA, COD_MAJOR_IMAGING, \ + COD_MAJOR_IMAGING_MINOR_DISPLAY) -/* Category[15:6] 0x006 */ -#define BLE_APPEARANCE_GENERIC_REMOTE 0x0180 +/* Category Remote Control [15:6] 0x006 */ +#define APPEARANCE_TO_COD_REMOTE_CONTROL(X) \ + X(BLE_APPEARANCE_GENERIC_REMOTE, 0x0180, COD_SERVICE_NA, COD_MAJOR_PERIPHERAL, \ + COD_MAJOR_PERIPH_MINOR_REMOTE_CONTROL) -/* Category[15:6] 0x007 */ -#define BLE_APPEARANCE_GENERIC_EYEGLASSES 0x01C0 +/* Category Eye-glasses [15:6] 0x007 */ +#define APPEARANCE_TO_COD_EYEGLASSES(X) \ + X(BLE_APPEARANCE_GENERIC_EYEGLASSES, 0x01C0, COD_SERVICE_NA, COD_MAJOR_WEARABLE, \ + COD_MAJOR_WEARABLE_MINOR_GLASSES) -/* Category[15:6] 0x008 */ +/* Category Tag [15:6] 0x008 */ #define BLE_APPEARANCE_GENERIC_TAG 0x0200 -/* Category[15:6] 0x009 */ +/* Category Keyring [15:6] 0x009 */ #define BLE_APPEARANCE_GENERIC_KEYRING 0x0240 -/* Category[15:6] 0x00A */ -#define BLE_APPEARANCE_GENERIC_MEDIA_PLAYER 0x0280 - -/* Category[15:6] 0x00B */ -#define BLE_APPEARANCE_GENERIC_BARCODE_SCANNER 0x02C0 - -/* Category[15:6] 0x00C */ -#define BLE_APPEARANCE_GENERIC_THERMOMETER 0x0300 -#define BLE_APPEARANCE_THERMOMETER_EAR 0x0301 - -/* Category[15:6] 0x00D */ -#define BLE_APPEARANCE_GENERIC_HEART_RATE 0x0340 -#define BLE_APPEARANCE_HEART_RATE_BELT 0x0341 - -/* Category[15:6] 0x00E */ -#define BLE_APPEARANCE_GENERIC_BLOOD_PRESSURE 0x0380 -#define BLE_APPEARANCE_BLOOD_PRESSURE_ARM 0x0381 -#define BLE_APPEARANCE_BLOOD_PRESSURE_WRIST 0x0382 - -/* Category[15:6] 0x00F */ -#define BLE_APPEARANCE_GENERIC_HID 0x03C0 -#define BLE_APPEARANCE_HID_KEYBOARD 0x03C1 -#define BLE_APPEARANCE_HID_MOUSE 0x03C2 -#define BLE_APPEARANCE_HID_JOYSTICK 0x03C3 -#define BLE_APPEARANCE_HID_GAMEPAD 0x03C4 -#define BLE_APPEARANCE_HID_DIGITIZER_TABLET 0x03C5 -#define BLE_APPEARANCE_HID_CARD_READER 0x03C6 -#define BLE_APPEARANCE_HID_DIGITAL_PEN 0x03C7 -#define BLE_APPEARANCE_HID_BARCODE_SCANNER 0x03C8 +/* Category Media Player [15:6] 0x00A */ +#define APPEARANCE_TO_COD_MEDIA_PLAYER(X) \ + X(BLE_APPEARANCE_GENERIC_MEDIA_PLAYER, 0x0280, COD_SERVICE_NA, COD_MAJOR_AUDIO, \ + COD_MINOR_UNCATEGORIZED) + +/* Category Barcode Scanner [15:6] 0x00B */ +#define APPEARANCE_TO_COD_BARCODE_SCANNER(X) \ + X(BLE_APPEARANCE_GENERIC_BARCODE_SCANNER, 0x02C0, COD_SERVICE_NA, COD_MAJOR_PERIPHERAL, \ + COD_MAJOR_PERIPH_MINOR_UNCATEGORIZED) + +/* Category Thermometer [15:6] 0x00C */ +#define APPEARANCE_TO_COD_THERMOMETER(X) \ + X(BLE_APPEARANCE_GENERIC_THERMOMETER, 0x0300, COD_SERVICE_NA, COD_MAJOR_HEALTH, \ + COD_MAJOR_HEALTH_MINOR_THERMOMETER) \ + X(BLE_APPEARANCE_THERMOMETER_EAR, 0x0301, COD_SERVICE_NA, COD_MAJOR_HEALTH, \ + COD_MAJOR_HEALTH_MINOR_THERMOMETER) + +/* Category Heart Rate Sensor [15:6] 0x00D */ +#define APPEARANCE_TO_COD_HEART_RATE_SENSOR(X) \ + X(BLE_APPEARANCE_GENERIC_HEART_RATE, 0x0340, COD_SERVICE_NA, COD_MAJOR_HEALTH, \ + COD_MAJOR_HEALTH_MINOR_HEART_PULSE_MONITOR) \ + X(BLE_APPEARANCE_HEART_RATE_BELT, 0x0341, COD_SERVICE_NA, COD_MAJOR_HEALTH, \ + COD_MAJOR_HEALTH_MINOR_HEART_PULSE_MONITOR) + +/* Category Blood Pressure [15:6] 0x00E */ +#define APPEARANCE_TO_COD_BLOOD_PRESSURE(X) \ + X(BLE_APPEARANCE_GENERIC_BLOOD_PRESSURE, 0x0380, COD_SERVICE_NA, COD_MAJOR_HEALTH, \ + COD_MAJOR_HEALTH_MINOR_BLOOD_MONITOR) \ + X(BLE_APPEARANCE_BLOOD_PRESSURE_ARM, 0x0381, COD_SERVICE_NA, COD_MAJOR_HEALTH, \ + COD_MAJOR_HEALTH_MINOR_BLOOD_MONITOR) \ + X(BLE_APPEARANCE_BLOOD_PRESSURE_WRIST, 0x0382, COD_SERVICE_NA, COD_MAJOR_HEALTH, \ + COD_MAJOR_HEALTH_MINOR_BLOOD_MONITOR) + +/* Category HID [15:6] 0x00F */ #define BLE_APPEARANCE_HID_TOUCHPAD 0x03C9 #define BLE_APPEARANCE_HID_PRESENTATION_REMOTE 0x03CA - -/* Category[15:6] 0x010 */ -#define BLE_APPEARANCE_GENERIC_GLUCOSE 0x0400 - -/* Category[15:6] 0x011 */ -#define BLE_APPEARANCE_GENERIC_WALKING 0x0440 -#define BLE_APPEARANCE_WALKING_IN_SHOE 0x0441 -#define BLE_APPEARANCE_WALKING_ON_SHOE 0x0442 -#define BLE_APPEARANCE_WALKING_ON_HIP 0x0443 - -/* Category[15:6] 0x012 */ +#define APPEARANCE_TO_COD_HID(X) \ + X(BLE_APPEARANCE_GENERIC_HID, 0x03C0, COD_SERVICE_NA, COD_MAJOR_PERIPHERAL, \ + COD_MAJOR_PERIPH_MINOR_UNCATEGORIZED) \ + X(BLE_APPEARANCE_HID_KEYBOARD, 0x03C1, COD_SERVICE_NA, COD_MAJOR_PERIPHERAL, \ + COD_MAJOR_PERIPH_MINOR_KEYBOARD) \ + X(BLE_APPEARANCE_HID_MOUSE, 0x03C2, COD_SERVICE_NA, COD_MAJOR_PERIPHERAL, \ + COD_MAJOR_PERIPH_MINOR_POINTING) \ + X(BLE_APPEARANCE_HID_JOYSTICK, 0x03C3, COD_SERVICE_NA, COD_MAJOR_PERIPHERAL, \ + COD_MAJOR_PERIPH_MINOR_JOYSTICK) \ + X(BLE_APPEARANCE_HID_GAMEPAD, 0x03C4, COD_SERVICE_NA, COD_MAJOR_PERIPHERAL, \ + COD_MAJOR_PERIPH_MINOR_GAMEPAD) \ + X(BLE_APPEARANCE_HID_DIGITIZER_TABLET, 0x03C5, COD_SERVICE_NA, COD_MAJOR_PERIPHERAL, \ + COD_MAJOR_PERIPH_MINOR_DIGITIZING_TABLET) \ + X(BLE_APPEARANCE_HID_CARD_READER, 0x03C6, COD_SERVICE_NA, COD_MAJOR_PERIPHERAL, \ + COD_MAJOR_PERIPH_MINOR_CARD_READER) \ + X(BLE_APPEARANCE_HID_DIGITAL_PEN, 0x03C7, COD_SERVICE_NA, COD_MAJOR_PERIPHERAL, \ + COD_MAJOR_PERIPH_MINOR_DIGITAL_PEN) \ + X(BLE_APPEARANCE_HID_BARCODE_SCANNER, 0x03C8, COD_SERVICE_NA, COD_MAJOR_PERIPHERAL, \ + COD_MAJOR_PERIPH_MINOR_UNCATEGORIZED) + +/* Category Glucose Meter [15:6] 0x010 */ +#define APPEARANCE_TO_COD_GLUCOSE_METER(X) \ + X(BLE_APPEARANCE_GENERIC_GLUCOSE, 0x0400, COD_SERVICE_NA, COD_MAJOR_HEALTH, \ + COD_MAJOR_HEALTH_MINOR_GLUCOSE_METER) + +/* Category Running Walking Sensor [15:6] 0x011 */ +#define APPEARANCE_TO_COD_RUNNING_WALKING_SENSOR(X) \ + X(BLE_APPEARANCE_GENERIC_WALKING, 0x0440, COD_SERVICE_NA, COD_MAJOR_HEALTH, \ + COD_MAJOR_HEALTH_MINOR_STEP_COUNTER) \ + X(BLE_APPEARANCE_WALKING_IN_SHOE, 0x0441, COD_SERVICE_NA, COD_MAJOR_HEALTH, \ + COD_MAJOR_HEALTH_MINOR_STEP_COUNTER) \ + X(BLE_APPEARANCE_WALKING_ON_SHOE, 0x0442, COD_SERVICE_NA, COD_MAJOR_HEALTH, \ + COD_MAJOR_HEALTH_MINOR_STEP_COUNTER) \ + X(BLE_APPEARANCE_WALKING_ON_HIP, 0x0443, COD_SERVICE_NA, COD_MAJOR_HEALTH, \ + COD_MAJOR_HEALTH_MINOR_STEP_COUNTER) + +/* Category Cycling [15:6] 0x012 */ #define BLE_APPEARANCE_GENERIC_CYCLING 0x0480 #define BLE_APPEARANCE_CYCLING_COMPUTER 0x0481 #define BLE_APPEARANCE_CYCLING_SPEED 0x0482 @@ -117,7 +180,7 @@ #define BLE_APPEARANCE_CYCLING_POWER 0x0484 #define BLE_APPEARANCE_CYCLING_SPEED_CADENCE 0x0485 -/* Category[15:6] 0x013 */ +/* Category Control Device [15:6] 0x013 */ #define BLE_APPEARANCE_GENERIC_CONTROL_DEVICE 0x04C0 #define BLE_APPEARANCE_SWITCH 0x04C1 #define BLE_APPEARANCE_MULTI_SWITCH 0x04C2 @@ -133,13 +196,13 @@ #define BLE_APPEARANCE_SWITCH_PUSH_BUTTON 0x04CC #define BLE_APPEARANCE_SWITCH_DIAL 0x04CD -/* Category[15:6] 0x014 */ +/* Category Network Device [15:6] 0x014 */ #define BLE_APPEARANCE_GENERIC_NETWORK_DEVICE 0x0500 #define BLE_APPEARANCE_NETWORK_DEVICE_ACCESS_POINT 0x0501 #define BLE_APPEARANCE_NETWORK_DEVICE_MESH_DEVICE 0x0502 #define BLE_APPEARANCE_NETWORK_DEVICE_MESH_NETWORK_PROXY 0x0503 -/* Category[15:6] 0x015 */ +/* Category Sensor [15:6] 0x015 */ #define BLE_APPEARANCE_GENERIC_SENSOR 0x0540 #define BLE_APPEARANCE_MOTION_SENSOR 0x0541 #define BLE_APPEARANCE_AIR_QUALITY_SENSOR 0x0542 @@ -167,7 +230,7 @@ #define BLE_APPEARANCE_SENSOR_FLAME_DETECTOR 0x0558 #define BLE_APPEARANCE_VEHICLE_TIRE_PRESSURE_SENSOR 0x0559 -/* Category[15:6] 0x016 */ +/* Category Light Fixtures [15:6] 0x016 */ #define BLE_APPEARANCE_GENERIC_LIGHT_FIXTURE 0x0580 #define BLE_APPEARANCE_WALL_LIGHT 0x0581 #define BLE_APPEARANCE_CEILING_LIGHT 0x0582 @@ -195,7 +258,7 @@ #define BLE_APPEARANCE_LOW_BAY_LIGHT 0x0598 #define BLE_APPEARANCE_HIGH_BAY_LIGHT 0x0599 -/* Category[15:6] 0x017 */ +/* Category Fan [15:6] 0x017 */ #define BLE_APPEARANCE_GENERIC_FAN 0x05C0 #define BLE_APPEARANCE_CEILING_FAN 0x05C1 #define BLE_APPEARANCE_AXIAL_FAN 0x05C2 @@ -204,7 +267,7 @@ #define BLE_APPEARANCE_DESK_FAN 0x05C5 #define BLE_APPEARANCE_WALL_FAN 0x05C6 -/* Category[15:6] 0x018 */ +/* Category HVAC [15:6] 0x018 */ #define BLE_APPEARANCE_GENERIC_HVAC 0x0600 #define BLE_APPEARANCE_HVAC_THERMOSTAT 0x0601 #define BLE_APPEARANCE_HVAC_HUMIDIFIER 0x0602 @@ -218,13 +281,13 @@ #define BLE_APPEARANCE_HVAC_FAN_HEATER 0x060A #define BLE_APPEARANCE_HVAC_AIR_CURTAIN 0x060B -/* Category[15:6] 0x019 */ +/* Category Air Conditioning [15:6] 0x019 */ #define BLE_APPEARANCE_GENERIC_AIR_CONDITIONING 0x0640 -/* Category[15:6] 0x01A */ +/* Category Humidifier [15:6] 0x01A */ #define BLE_APPEARANCE_GENERIC_HUMIDIFIER 0x0680 -/* Category[15:6] 0x01B */ +/* Category Heating [15:6] 0x01B */ #define BLE_APPEARANCE_GENERIC_HEATING 0x06C0 #define BLE_APPEARANCE_HEATING_RADIATOR 0x06C1 #define BLE_APPEARANCE_HEATING_BOILER 0x06C2 @@ -234,7 +297,7 @@ #define BLE_APPEARANCE_HEATING_FAN_HEATER 0x06C6 #define BLE_APPEARANCE_HEATING_AIR_CURTAIN 0x06C7 -/* Category[15:6] 0x01C */ +/* Category Access Control [15:6] 0x01C */ #define BLE_APPEARANCE_GENERIC_ACCESS_CONTROL 0x0700 #define BLE_APPEARANCE_ACCESS_DOOR 0x0701 #define BLE_APPEARANCE_ACCESS_CONTROL_GARAGE_DOOR 0x0702 @@ -246,7 +309,7 @@ #define BLE_APPEARANCE_ACCESS_CONTROL_DOOR_LOCK 0x0708 #define BLE_APPEARANCE_ACCESS_CONTROL_LOCKER 0x0709 -/* Category[15:6] 0x01D */ +/* Category Motorized Device [15:6] 0x01D */ #define BLE_APPEARANCE_GENERIC_MOTORIZED_DEVICE 0x0740 #define BLE_APPEARANCE_MOTORIZED_GATE 0x0741 #define BLE_APPEARANCE_MOTORIZED_AWNING 0x0742 @@ -254,14 +317,14 @@ #define BLE_APPEARANCE_MOTORIZED_CURTAINS 0x0744 #define BLE_APPEARANCE_MOTORIZED_SCREEN 0x0745 -/* Category[15:6] 0x01E */ +/* Category Power Device [15:6] 0x01E */ #define BLE_APPEARANCE_GENERIC_POWER_DEVICE 0x0780 #define BLE_APPEARANCE_POWER_OUTLET 0x0781 #define BLE_APPEARANCE_POWER_STRIP 0x0782 #define BLE_APPEARANCE_POWER_PLUG 0x0783 #define BLE_APPEARANCE_POWER_SUPPLY 0x0784 -/* Category[15:6] 0x01F */ +/* Category Light Source [15:6] 0x01F */ #define BLE_APPEARANCE_GENERIC_LIGHT_SOURCE 0x07C0 #define BLE_APPEARANCE_LIGHT_SOURCE_INCANDESCENT_LIGHT_BULB 0x07C1 #define BLE_APPEARANCE_LIGHT_SOURCE_LED_LAMP 0x07C2 @@ -272,7 +335,7 @@ #define BLE_APPEARANCE_LIGHT_SOURCE_LOW_VOLTAGE_HALOGEN 0x07C7 #define BLE_APPEARANCE_LIGHT_SOURCE_ORGANIC_LIGHT_EMITTING_DIODE_OLED 0x07C8 -/* Category[15:6] 0x020 */ +/* Category Window Covering [15:6] 0x020 */ #define BLE_APPEARANCE_GENERIC_WINDOW_COVERING 0x0800 #define BLE_APPEARANCE_WINDOW_COVERING_WINDOW_SHADES 0x0801 #define BLE_APPEARANCE_WINDOW_COVERING_WINDOW_BLINDS 0x0802 @@ -281,7 +344,7 @@ #define BLE_APPEARANCE_WINDOW_COVERING_EXTERIOR_SHUTTER 0x0805 #define BLE_APPEARANCE_WINDOW_COVERING_EXTERIOR_SCREEN 0x0806 -/* Category[15:6] 0x021 */ +/* Category Audio Sink [15:6] 0x021 */ #define BLE_APPEARANCE_GENERIC_AUDIO_SINK 0x0840 #define BLE_APPEARANCE_AUDIO_SINK_STANDALONE_SPEAKER 0x0841 #define BLE_APPEARANCE_AUDIO_SINK_SOUNDBAR 0x0842 @@ -289,7 +352,7 @@ #define BLE_APPEARANCE_AUDIO_SINK_STANDMOUNTED_SPEAKER 0x0844 #define BLE_APPEARANCE_AUDIO_SINK_SPEAKERPHONE 0x0845 -/* Category[15:6] 0x022 */ +/* Category Audio Source [15:6] 0x022 */ #define BLE_APPEARANCE_GENERIC_AUDIO_SOURCE 0x0880 #define BLE_APPEARANCE_AUDIO_SOURCE_MICROPHONE 0x0881 #define BLE_APPEARANCE_AUDIO_SOURCE_ALARM 0x0882 @@ -301,7 +364,7 @@ #define BLE_APPEARANCE_AUDIO_SOURCE_BROADCASTING_ROOM 0x0888 #define BLE_APPEARANCE_AUDIO_SOURCE_AUDITORIUM 0x0889 -/* Category[15:6] 0x023 */ +/* Category Motorized Vehicle [15:6] 0x023 */ #define BLE_APPEARANCE_GENERIC_MOTORIZED_VEHICLE 0x08C0 #define BLE_APPEARANCE_MOTORIZED_VEHICLE_CAR 0x08C1 #define BLE_APPEARANCE_MOTORIZED_VEHICLE_LARGE_GOODS 0x08C2 @@ -319,7 +382,7 @@ #define BLE_APPEARANCE_MOTORIZED_VEHICLE_CAMPER_CARAVAN 0x08CE #define BLE_APPEARANCE_MOTORIZED_VEHICLE_RECREATIONAL_VEHICLE_MOTOR_HOME 0x08CF -/* Category[15:6] 0x024 */ +/* Category Domestic Appliance [15:6] 0x024 */ #define BLE_APPEARANCE_GENERIC_DOMESTIC_APPLIANCE 0x0900 #define BLE_APPEARANCE_DOMESTIC_APPLIANCE_REFRIGERATOR 0x0901 #define BLE_APPEARANCE_DOMESTIC_APPLIANCE_FREEZER 0x0902 @@ -337,21 +400,32 @@ #define BLE_APPEARANCE_DOMESTIC_APPLIANCE_RICE_COOKER 0x090E #define BLE_APPEARANCE_DOMESTIC_APPLIANCE_CLOTHES_STEAMER 0x090F -/* Category[15:6] 0x025 */ -#define BLE_APPEARANCE_GENERIC_WEARABLE_AUDIO_DEVICE 0x0940 -#define BLE_APPEARANCE_WEARABLE_AUDIO_DEVICE_EARBUD 0x0941 -#define BLE_APPEARANCE_WEARABLE_AUDIO_DEVICE_HEADSET 0x0942 -#define BLE_APPEARANCE_WEARABLE_AUDIO_DEVICE_HEADPHONES 0x0943 -#define BLE_APPEARANCE_WEARABLE_AUDIO_DEVICE_NECK_BAND 0x0944 - -/* Category[15:6] 0x026 */ +/* Category Wearable Audio Device [15:6] 0x025 */ +#define APPEARANCE_TO_COD_WEARABLE_AUDIO_DEVICE(X) \ + X(BLE_APPEARANCE_GENERIC_WEARABLE_AUDIO_DEVICE, 0x0940, \ + (COD_SERVICE_AUDIO | COD_SERVICE_RENDERING) >> 8, (COD_MAJOR_AUDIO | COD_SERVICE_LE_AUDIO), \ + COD_MAJOR_AUDIO_MINOR_WEARABLE_HEADSET) \ + X(BLE_APPEARANCE_WEARABLE_AUDIO_DEVICE_EARBUD, 0x0941, \ + (COD_SERVICE_AUDIO | COD_SERVICE_RENDERING) >> 8, (COD_MAJOR_AUDIO | COD_SERVICE_LE_AUDIO), \ + COD_MAJOR_AUDIO_MINOR_WEARABLE_HEADSET) \ + X(BLE_APPEARANCE_WEARABLE_AUDIO_DEVICE_HEADSET, 0x0942, \ + (COD_SERVICE_AUDIO | COD_SERVICE_RENDERING) >> 8, (COD_MAJOR_AUDIO | COD_SERVICE_LE_AUDIO), \ + COD_MAJOR_AUDIO_MINOR_WEARABLE_HEADSET) \ + X(BLE_APPEARANCE_WEARABLE_AUDIO_DEVICE_HEADPHONES, 0x0943, \ + (COD_SERVICE_AUDIO | COD_SERVICE_RENDERING) >> 8, (COD_MAJOR_AUDIO | COD_SERVICE_LE_AUDIO), \ + COD_MAJOR_AUDIO_MINOR_WEARABLE_HEADSET) \ + X(BLE_APPEARANCE_WEARABLE_AUDIO_DEVICE_NECK_BAND, 0x0944, \ + (COD_SERVICE_AUDIO | COD_SERVICE_RENDERING) >> 8, (COD_MAJOR_AUDIO | COD_SERVICE_LE_AUDIO), \ + COD_MAJOR_AUDIO_MINOR_WEARABLE_HEADSET) + +/* Category Aircraft [15:6] 0x026 */ #define BLE_APPEARANCE_GENERIC_AIRCRAFT 0x0980 #define BLE_APPEARANCE_AIRCRAFT_LIGHT 0x0981 #define BLE_APPEARANCE_AIRCRAFT_MICROLIGHT 0x0982 #define BLE_APPEARANCE_AIRCRAFT_PARAGLIDER 0x0983 #define BLE_APPEARANCE_AIRCRAFT_LARGE_PASSENGER 0x0984 -/* Category[15:6] 0x027 */ +/* Category Audio/Video Equipment [15:6] 0x027 */ #define BLE_APPEARANCE_GENERIC_AV_EQUIPMENT 0x09C0 #define BLE_APPEARANCE_AV_EQUIPMENT_AMPLIFIER 0x09C1 #define BLE_APPEARANCE_AV_EQUIPMENT_RECEIVER 0x09C2 @@ -364,65 +438,71 @@ #define BLE_APPEARANCE_AV_EQUIPMENT_OPTICAL_DISC_PLAYER 0x09C9 #define BLE_APPEARANCE_AV_EQUIPMENT_SET_TOP_BOX 0x09CA -/* Category[15:6] 0x028 */ +/* Category Display Equipment [15:6] 0x028 */ #define BLE_APPEARANCE_GENERIC_DISPLAY_EQUIPMENT 0x0A00 #define BLE_APPEARANCE_DISPLAY_EQUIPMENT_TELEVISION 0x0A01 #define BLE_APPEARANCE_DISPLAY_EQUIPMENT_MONITOR 0x0A02 #define BLE_APPEARANCE_DISPLAY_EQUIPMENT_PROJECTOR 0x0A03 -/* Category[15:6] 0x029 */ +/* Category Hearing Aid [15:6] 0x029 */ #define BLE_APPEARANCE_GENERIC_HEARING_AID 0x0A40 #define BLE_APPEARANCE_HEARING_AID_IN_EAR 0x0A41 #define BLE_APPEARANCE_HEARING_AID_BEHIND_EAR 0x0A42 #define BLE_APPEARANCE_HEARING_AID_COCHLLEAR_IMPLANT 0x0A43 -/* Category[15:6] 0x02A */ +/* Category Gaming [15:6] 0x02A */ #define BLE_APPEARANCE_GENERIC_GAMING 0x0A80 #define BLE_APPEARANCE_GAMING_HOME_VIDEO_GAME_CONSOLE 0x0A81 #define BLE_APPEARANCE_GAMING_PORTABLE_HANDHELD_CONSOLE 0x0A82 -/* Category[15:6] 0x02B */ +/* Category Signage [15:6] 0x02B */ #define BLE_APPEARANCE_GENERIC_SIGNAGE 0x0AC0 #define BLE_APPEARANCE_SIGNAGE_DIGITAL 0x0AC1 #define BLE_APPEARANCE_SIGNAGE_ELECTRONIC_LABEL 0x0AC2 -/* Category[15:6] 0x031 */ -#define BLE_APPEARANCE_GENERIC_PULSE_OXIMETER 0x0C40 -#define BLE_APPEARANCE_PULSE_OXIMETER_FINGERTIP 0x0C41 -#define BLE_APPEARANCE_PULSE_OXIMETER_WRIST 0x0C42 - -/* Category[15:6] 0x032 */ -#define BLE_APPEARANCE_GENERIC_WEIGHT 0x0C80 - -/* Category[15:6] 0x033 */ +/* Category Pulse Oximeter [15:6] 0x031 */ +#define APPEARANCE_TO_COD_PULSE_OXIMETER(X) \ + X(BLE_APPEARANCE_GENERIC_PULSE_OXIMETER, 0x0C40, COD_SERVICE_NA, COD_MAJOR_HEALTH, \ + COD_MAJOR_HEALTH_MINOR_PULSE_OXIMETER) \ + X(BLE_APPEARANCE_PULSE_OXIMETER_FINGERTIP, 0x0C41, COD_SERVICE_NA, COD_MAJOR_HEALTH, \ + COD_MAJOR_HEALTH_MINOR_PULSE_OXIMETER) \ + X(BLE_APPEARANCE_PULSE_OXIMETER_WRIST, 0x0C42, COD_SERVICE_NA, COD_MAJOR_HEALTH, \ + COD_MAJOR_HEALTH_MINOR_PULSE_OXIMETER) + +/* Category Weight Scale [15:6] 0x032 */ +#define APPEARANCE_TO_COD_WEIGHT_SCALE(X) \ + X(BLE_APPEARANCE_GENERIC_WEIGHT, 0x0C80, COD_SERVICE_NA, COD_MAJOR_HEALTH, \ + COD_MAJOR_HEALTH_MINOR_WEIGHING_SCALE) + +/* Category Personal Mobility Device [15:6] 0x033 */ #define BLE_APPEARANCE_GENERIC_PERSONAL_MOBILITY_DEVICE 0x0CC0 #define BLE_APPEARANCE_PERSONAL_MOBILITY_DEVICE_POWERED_WHEELCHAIR 0x0CC1 #define BLE_APPEARANCE_PERSONAL_MOBILITY_DEVICE_MOBILITY_SCOOTER 0x0CC2 -/* Category[15:6] 0x034 */ +/* Category Continuous Glucose Monitor [15:6] 0x034 */ #define BLE_APPEARANCE_GENERIC_CONTINUOUS_GLUCOSE_MONITOR 0x0D00 -/* Category[15:6] 0x035 */ +/* Category Insulin Pump [15:6] 0x035 */ #define BLE_APPEARANCE_GENERIC_INSULIN_PUMP 0x0D40 #define BLE_APPEARANCE_INSULIN_PUMP_DURABLE 0x0D41 #define BLE_APPEARANCE_INSULIN_PUMP_PATCH 0x0D44 #define BLE_APPEARANCE_INSULIN_PUMP_PEN 0x0D48 -/* Category[15:6] 0x036 */ +/* Category Medication Delivery [15:6] 0x036 */ #define BLE_APPEARANCE_GENERIC_MEDICATION_DELIVERY 0x0D80 -/* Category[15:6] 0x037 */ +/* Category Spirometer [15:6] 0x037 */ #define BLE_APPEARANCE_GENERIC_SPIROMETER 0x0DC0 #define BLE_APPEARANCE_SPIROMETER_HANDHELD 0x0DC1 -/* Category[15:6] 0x051 */ +/* Category Outdoor Sports Activity [15:6] 0x051 */ #define BLE_APPEARANCE_GENERIC_OUTDOOR_SPORTS 0x1440 #define BLE_APPEARANCE_OUTDOOR_SPORTS_LOCATION 0x1441 #define BLE_APPEARANCE_OUTDOOR_SPORTS_LOCATION_AND_NAV 0x1442 #define BLE_APPEARANCE_OUTDOOR_SPORTS_LOCATION_POD 0x1443 #define BLE_APPEARANCE_OUTDOOR_SPORTS_LOCATION_POD_AND_NAV 0x1444 -/* Category[15:6] 0x052 */ +/* Category Industrial Measurement Device [15:6] 0x052 */ #define BLE_APPEARANCE_GENERIC_INDUSTRIAL_MEASUREMENT_DEVICE 0x1480 #define BLE_APPEARANCE_INDUSTRIAL_MEASUREMENT_DEVICE_TORQUE_TESTING 0x1481 #define BLE_APPEARANCE_INDUSTRIAL_MEASUREMENT_DEVICE_CALIPER 0x1482 @@ -431,7 +511,7 @@ #define BLE_APPEARANCE_INDUSTRIAL_MEASUREMENT_DEVICE_HEIGHT_GAUGE 0x1485 #define BLE_APPEARANCE_INDUSTRIAL_MEASUREMENT_DEVICE_FORCE_GAUGE 0x1486 -/* Category[15:6] 0x053 */ +/* Category Industrial Tools [15:6] 0x053 */ #define BLE_APPEARANCE_GENERIC_INDUSTRIAL_TOOLS 0x14C0 #define BLE_APPEARANCE_INDUSTRIAL_TOOLS_MACHINE_TOOL_HOLDER 0x14C1 #define BLE_APPEARANCE_INDUSTRIAL_TOOLS_GENERIC_CLAMPING_DEVICE 0x14C2 @@ -443,4 +523,39 @@ #define BLE_APPEARANCE_INDUSTRIAL_TOOLS_TORQUE_WRENCH 0x14C8 #define BLE_APPEARANCE_INDUSTRIAL_TOOLS_TORQUE_SCREWDRIVER 0x14C9 +/* + * Collection of all the appearance to COD functions per category. + * Note: Add the macro call here if a new definition is added. + */ +#define APPEARANCE_TO_COD(X) \ + APPEARANCE_TO_COD_UNKNOWN(X) \ + APPEARANCE_TO_COD_PHONE(X) \ + APPEARANCE_TO_COD_COMPUTER(X) \ + APPEARANCE_TO_COD_WATCH(X) \ + APPEARANCE_TO_COD_DISPLAY(X) \ + APPEARANCE_TO_COD_REMOTE_CONTROL(X) \ + APPEARANCE_TO_COD_EYEGLASSES(X) \ + APPEARANCE_TO_COD_MEDIA_PLAYER(X) \ + APPEARANCE_TO_COD_BARCODE_SCANNER(X) \ + APPEARANCE_TO_COD_THERMOMETER(X) \ + APPEARANCE_TO_COD_HEART_RATE_SENSOR(X) \ + APPEARANCE_TO_COD_BLOOD_PRESSURE(X) \ + APPEARANCE_TO_COD_HID(X) \ + APPEARANCE_TO_COD_GLUCOSE_METER(X) \ + APPEARANCE_TO_COD_RUNNING_WALKING_SENSOR(X) \ + APPEARANCE_TO_COD_WEARABLE_AUDIO_DEVICE(X) \ + APPEARANCE_TO_COD_PULSE_OXIMETER(X) \ + APPEARANCE_TO_COD_WEIGHT_SCALE(X) + +// Generates the BLE appearance definitions for reference +#define GENERATE_BLE_APPEARANCE_DEFINITIONS(_appearance, _value, _service, _major, _minor) \ + constexpr uint16_t _appearance = _value; + +#define ADD_APPEARANCE_TO_COD_CASE(_appearance, _value, _service, _major, _minor) \ + case _appearance: \ + return DEV_CLASS{_service, _major, _minor}; + +// Generate the actual definition for each appearance. +APPEARANCE_TO_COD(GENERATE_BLE_APPEARANCE_DEFINITIONS) + #endif // BLE_APPEARANCE_H
\ No newline at end of file diff --git a/system/stack/include/bt_dev_class.h b/system/stack/include/bt_dev_class.h index ca951532ce..333376c071 100644 --- a/system/stack/include/bt_dev_class.h +++ b/system/stack/include/bt_dev_class.h @@ -24,8 +24,6 @@ constexpr size_t kDevClassLength = 3; typedef std::array<uint8_t, kDevClassLength> DEV_CLASS; /* Device class */ -inline constexpr DEV_CLASS kDevClassEmpty = {}; - /*************************** * major device class field * Note: All values are deduced by basing BIT_X to BIT_8, values as per @@ -48,6 +46,7 @@ inline constexpr DEV_CLASS kDevClassEmpty = {}; * Note: All values are deduced by basing BIT_X to BIT_8, values as per * BT-spec assigned-numbers. ***************************/ +#define COD_SERVICE_NA 0x0000 #define COD_SERVICE_LMTD_DISCOVER 0x0020 // BIT13 (eg. 13-8 = BIT5 = 0x0020) #define COD_SERVICE_LE_AUDIO 0x0040 // BIT14 #define COD_SERVICE_POSITIONING 0x0100 // BIT16 @@ -117,6 +116,7 @@ inline constexpr DEV_CLASS kDevClassEmpty = {}; /* Minor Device class field - Peripheral Major Class (COD_MAJOR_PERIPHERAL) */ /* Bits 6-7 independently specify mouse, keyboard, or combo mouse/keyboard */ +#define COD_MAJOR_PERIPH_MINOR_UNCATEGORIZED 0x00 #define COD_MAJOR_PERIPH_MINOR_KEYBOARD 0x40 // BIT6 #define COD_MAJOR_PERIPH_MINOR_POINTING 0x80 // BIT7 #define COD_MAJOR_PERIPH_MINOR_KEYBOARD_AND_POINTING_DEVICE 0xC0 // BIT6 | BIT7 @@ -167,7 +167,7 @@ inline constexpr DEV_CLASS kDevClassEmpty = {}; #define COD_MAJOR_HEALTH_MINOR_PULSE_OXIMETER 0x14 // BIT2 | BIT4 #define COD_MAJOR_HEALTH_MINOR_HEART_PULSE_MONITOR 0x18 // BIT3 | BIT4 #define COD_MAJOR_HEALTH_MINOR_HEALTH_DATA_DISPLAY 0x1C // BIT2 | BIT3 | BIT4 -#define COD_MAJO_HEALTH_MINOR_STEP_COUNTER 0x20 // BIT5 +#define COD_MAJOR_HEALTH_MINOR_STEP_COUNTER 0x20 // BIT5 #define COD_MAJOR_HEALTH_MINOR_BODY_COMPOSITION_ANALYZER 0x24 // BIT2 | BIT5 #define COD_MAJOR_HEALTH_MINOR_PEAK_FLOW_MONITOR 0x28 // BIT3 | BIT5 #define COD_MAJOR_HEALTH_MINOR_MEDICATION_MONITOR 0x2C // BIT2 | BIT3 | BIT5 @@ -215,7 +215,7 @@ inline constexpr DEV_CLASS kDevClassEmpty = {}; #define BTM_COD_MINOR_GLUCOSE_METER COD_MAJOR_HEALTH_MINOR_GLUCOSE_METER #define BTM_COD_MINOR_PULSE_OXIMETER COD_MAJOR_HEALTH_MINOR_PULSE_OXIMETER #define BTM_COD_MINOR_HEART_PULSE_MONITOR COD_MAJOR_HEALTH_MINOR_HEART_PULSE_MONITOR -#define BTM_COD_MINOR_STEP_COUNTER COD_MAJO_HEALTH_MINOR_STEP_COUNTER +#define BTM_COD_MINOR_STEP_COUNTER COD_MAJOR_HEALTH_MINOR_STEP_COUNTER /*************************** * major device class field @@ -249,6 +249,8 @@ inline constexpr DEV_CLASS kDevClassEmpty = {}; #define BTM_COD_SERVICE_CLASS_LO_B 0x00E0 #define BTM_COD_SERVICE_CLASS_MASK 0xFFE0 +inline constexpr DEV_CLASS kDevClassEmpty = {COD_SERVICE_NA, COD_MAJOR_MISC, + COD_MINOR_UNCATEGORIZED}; inline constexpr DEV_CLASS kDevClassUnclassified = {0x00, BTM_COD_MAJOR_UNCLASSIFIED, BTM_COD_MINOR_UNCLASSIFIED}; diff --git a/system/stack/l2cap/l2c_link.cc b/system/stack/l2cap/l2c_link.cc index b81c5f33e4..426a12a2ba 100644 --- a/system/stack/l2cap/l2c_link.cc +++ b/system/stack/l2cap/l2c_link.cc @@ -210,60 +210,34 @@ void l2c_link_sec_comp(RawAddress p_bda, tBT_TRANSPORT transport, void* p_ref_da return; } - if (com::android::bluetooth::flags::l2cap_p_ccb_check_rewrite()) { - if (!p_ref_data) { - log::warn("Argument p_ref_data is NULL"); - return; - } + if (!p_ref_data) { + log::warn("Argument p_ref_data is NULL"); + return; + } - /* Match p_ccb with p_ref_data returned by sec manager */ - p_ccb = (tL2C_CCB*)p_ref_data; + /* Match p_ccb with p_ref_data returned by sec manager */ + p_ccb = (tL2C_CCB*)p_ref_data; - if (p_lcb != p_ccb->p_lcb) { - log::warn("p_ref_data doesn't match with sec manager record"); - return; - } + if (p_lcb != p_ccb->p_lcb) { + log::warn("p_ref_data doesn't match with sec manager record"); + return; + } - switch (btm_status) { - case tBTM_STATUS::BTM_SUCCESS: - l2c_csm_execute(p_ccb, L2CEVT_SEC_COMP, &ci); - break; + switch (btm_status) { + case tBTM_STATUS::BTM_SUCCESS: + l2c_csm_execute(p_ccb, L2CEVT_SEC_COMP, &ci); + break; - case tBTM_STATUS::BTM_DELAY_CHECK: - /* start a timer - encryption change not received before L2CAP connect - * req */ - alarm_set_on_mloop(p_ccb->l2c_ccb_timer, L2CAP_DELAY_CHECK_SM4_TIMEOUT_MS, - l2c_ccb_timer_timeout, p_ccb); - return; + case tBTM_STATUS::BTM_DELAY_CHECK: + /* start a timer - encryption change not received before L2CAP connect + * req */ + alarm_set_on_mloop(p_ccb->l2c_ccb_timer, L2CAP_DELAY_CHECK_SM4_TIMEOUT_MS, + l2c_ccb_timer_timeout, p_ccb); + return; - default: - l2c_csm_execute(p_ccb, L2CEVT_SEC_COMP_NEG, &ci); - break; - } - } else { - /* Match p_ccb with p_ref_data returned by sec manager */ - for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_next_ccb) { - p_next_ccb = p_ccb->p_next_ccb; - - if (p_ccb == p_ref_data) { - switch (btm_status) { - case tBTM_STATUS::BTM_SUCCESS: - l2c_csm_execute(p_ccb, L2CEVT_SEC_COMP, &ci); - break; - - case tBTM_STATUS::BTM_DELAY_CHECK: - /* start a timer - encryption change not received before L2CAP - * connect req */ - alarm_set_on_mloop(p_ccb->l2c_ccb_timer, L2CAP_DELAY_CHECK_SM4_TIMEOUT_MS, - l2c_ccb_timer_timeout, p_ccb); - return; - - default: - l2c_csm_execute(p_ccb, L2CEVT_SEC_COMP_NEG, &ci); - break; - } - } - } + default: + l2c_csm_execute(p_ccb, L2CEVT_SEC_COMP_NEG, &ci); + break; } } diff --git a/system/test/Android.bp b/system/test/Android.bp index 595f148754..c965355dcc 100644 --- a/system/test/Android.bp +++ b/system/test/Android.bp @@ -618,11 +618,8 @@ cc_defaults { name: "mts_defaults", target: { android: { - test_config_template: ":BluetoothTestConfigTemplate", - test_suites: [ - "mts-bluetooth", - "mts-bt", - ], + test_config_template: ":BluetoothGTestConfigTemplate", + test_suites: ["mts-bt"], }, }, compile_multilib: "both", |