summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TEST_MAPPING3
-rw-r--r--android/app/jni/com_android_bluetooth_gatt.cpp4
-rw-r--r--android/app/src/com/android/bluetooth/gatt/CallbackInfo.java7
-rw-r--r--android/app/src/com/android/bluetooth/gatt/ContextMap.java99
-rw-r--r--android/app/src/com/android/bluetooth/gatt/GattNativeInterface.java64
-rw-r--r--android/app/src/com/android/bluetooth/gatt/GattObjectsFactory.java10
-rw-r--r--android/app/src/com/android/bluetooth/gatt/GattService.java1445
-rw-r--r--android/app/src/com/android/bluetooth/hearingaid/HearingAidService.java12
-rw-r--r--android/app/src/com/android/bluetooth/hfp/HeadsetService.java22
-rw-r--r--android/app/src/com/android/bluetooth/le_scan/AdvtFilterOnFoundOnLostInfo.java (renamed from android/app/src/com/android/bluetooth/gatt/AdvtFilterOnFoundOnLostInfo.java)2
-rw-r--r--android/app/src/com/android/bluetooth/le_scan/AppScanStats.java21
-rw-r--r--android/app/src/com/android/bluetooth/le_scan/ScanManager.java56
-rw-r--r--android/app/src/com/android/bluetooth/le_scan/TransitionalScanHelper.java1618
-rw-r--r--android/app/tests/robotests/src/com/android/bluetooth/opp/OppSendFileInfoTest.java12
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/a2dp/A2dpCodecConfigTest.java8
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/a2dp/A2dpServiceBinderTest.java6
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/a2dp/A2dpServiceTest.java8
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/a2dp/A2dpStateMachineTest.java8
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/a2dpsink/A2dpSinkServiceBinderTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/a2dpsink/A2dpSinkServiceTest.java6
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/a2dpsink/A2dpSinkStateMachineTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/a2dpsink/A2dpSinkStreamHandlerTest.java6
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/audio_util/BrowsablePlayerConnectorTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/audio_util/BrowserPlayerWrapperTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/audio_util/ImageTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/audio_util/MediaPlayerListTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/audio_util/MediaPlayerWrapperTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/audio_util/MetadataTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/avrcp/AvrcpVolumeManagerTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpBipClientTest.java6
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerServiceBinderTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerServiceTest.java6
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerStateMachineTest.java6
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtProviderTest.java6
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpPlayerTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/bas/BatteryServiceBinderTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/bass_client/BassClientServiceTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/bass_client/BleBroadcastAssistantBinderTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/btservice/ActiveDeviceManagerTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterPropertiesTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceBinderTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceFactoryResetTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceRestartTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceTest.java6
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/btservice/AudioRoutingManagerTest.java8
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/btservice/BondStateMachineTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/btservice/CompanionManagerTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/btservice/DataMigrationTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/btservice/MetricsLoggerTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/btservice/PhonePolicyTest.java6
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/btservice/ProfileServiceTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/btservice/RemoteDevicesTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/btservice/SilenceDeviceManagerTest.java8
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/btservice/bluetoothKeystore/BluetoothKeystoreServiceTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/btservice/storage/DatabaseManagerTest.java6
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/content_profiles/ContentProfileErrorReportUtilsTest.java1
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/csip/BluetoothCsisBinderTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/csip/CsipSetCoordinatorServiceTest.java8
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/csip/CsipSetCoordinatorStateMachineTest.java11
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/gatt/AdvertiseManagerTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/gatt/AppAdvertiseStatsTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/gatt/ContextMapTest.java12
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/gatt/DistanceMeasurementManagerTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/gatt/DistanceMeasurementTrackerTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/gatt/GattDebugUtilsTest.java12
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/gatt/GattServiceBinderTest.java36
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/gatt/GattServiceTest.java246
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/hap/HapClientNativeInterfaceTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/hap/HapClientStateMachineTest.java11
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/hap/HapClientTest.java8
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/hearingaid/HearingAidNativeInterfaceTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/hearingaid/HearingAidServiceTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/hearingaid/HearingAidStateMachineTest.java8
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/hfp/AtPhonebookTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/hfp/BluetoothHeadsetBinderTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetPhoneStateTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetServiceAndStateMachineTest.java46
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetServiceTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetStateMachineTest.java6
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/hfpclient/HeadsetClientServiceBinderTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/hfpclient/HeadsetClientServiceTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachineTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/hfpclient/HfpNativeInterfaceTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/hfpclient/VendorCommandResponseProcessorTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/hfpclient/connserv/HeadsetClientServiceInterfaceTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/hfpclient/connserv/HfpClientConnectionServiceTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/hfpclient/connserv/HfpClientDeviceBlockTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/hid/BluetoothHidDeviceBinderTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/hid/HidDeviceNativeInterfaceTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/hid/HidDeviceTest.java8
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/hid/HidHostServiceBinderTest.java6
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/hid/HidHostServiceTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/le_audio/ContentControlIdKeeperTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioBinderTest.java6
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioBroadcastServiceTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioBroadcasterNativeInterfaceTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioNativeInterfaceTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioServiceTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioStateMachineTest.java8
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioTmapGattServerTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/le_scan/AdvtFilterOnFoundOnLostInfoTest.java (renamed from android/app/tests/unit/src/com/android/bluetooth/gatt/AdvtFilterOnFoundOnLostInfoTest.java)2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/le_scan/AppScanStatsTest.java20
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/le_scan/PeriodicScanManagerTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/le_scan/ScanManagerTest.java11
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/le_scan/TransitionalScanHelperTest.java400
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapContentObserverTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapContentTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapConvoContactElementTest.java14
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapMasInstanceTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapObexServerTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapServiceBinderTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapServiceTest.java6
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapSmsPduTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/map/SmsMmsContactsTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/mapapi/BluetoothMapEmailProviderTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/mapapi/BluetoothMapIMProviderTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/mapclient/MapClientContentTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/mapclient/MapClientServiceBinderTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/mapclient/MapClientServiceTest.java6
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/mapclient/MapClientStateMachineTest.java6
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/mapclient/MapClientTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/mapclient/MnsObexServerTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/mcp/McpServiceTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/mcp/MediaControlGattServiceTest.java6
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/mcp/MediaControlProfileTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppBtEnableActivityTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppBtEnablingActivityTest.java6
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppHandoverReceiverTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppLauncherActivityTest.java6
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppManagerTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppNotificationTest.java6
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppObexClientSessionTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppObexServerSessionTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppPreferenceTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppReceiverTest.java6
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppSendFileInfoTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppServiceCleanupTest.java6
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppServiceTest.java6
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppTransferActivityTest.java6
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppTransferHistoryTest.java6
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppTransferTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppUtilityTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/opp/IncomingFileConfirmActivityTest.java6
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/pan/BluetoothTetheringNetworkFactoryTest.java12
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/pan/PanServiceBinderTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/pan/PanServiceTest.java6
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapAuthenticatorTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapCallLogComposerTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapConfigTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapObexServerTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapServiceBinderTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapServiceTest.java6
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapSimVcardManagerTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapUtilsTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapVcardManagerNestedClassesTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapVcardManagerTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/pbap/HandlerForStringBufferTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/pbap/PbapStateMachineTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/pbapclient/BluetoothPbapRequestTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/pbapclient/CallLogPullRequestTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientConnectionHandlerTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientServiceTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientStateMachineTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/sap/SapRilReceiverHidlTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/sap/SapRilReceiverTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/sap/SapServerTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/sap/SapServiceTest.java8
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/sdp/DipTest.java8
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/tbs/TbsGattTest.java6
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/tbs/TbsGenericTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/telephony/BluetoothInCallServiceTest.java6
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/telephony/CallInfoTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlNativeInterfaceTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlServiceTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlStateMachineTest.java8
-rw-r--r--flags/gap.aconfig7
-rw-r--r--flags/map.aconfig8
-rw-r--r--framework/api/system-current.txt2
-rw-r--r--framework/java/android/bluetooth/BluetoothAdapter.java6
-rw-r--r--framework/java/android/bluetooth/BluetoothLeAudio.java2
-rw-r--r--sysprop/Android.bp1
-rw-r--r--sysprop/device_id.sysprop26
-rw-r--r--sysprop/exported_include/android_bluetooth_sysprop.h1
-rw-r--r--system/bta/le_audio/client.cc35
-rw-r--r--system/btif/Android.bp1
-rw-r--r--system/btif/src/btif_a2dp.cc36
-rw-r--r--system/btif/src/btif_core.cc23
-rw-r--r--system/btif/src/btif_sock.cc16
-rw-r--r--system/btif/src/btif_sock_l2cap.cc14
-rw-r--r--system/log/src/vlog_android.cc11
-rw-r--r--system/log/src/vlog_test.cc57
-rw-r--r--system/test/suite/Android.bp9
192 files changed, 3257 insertions, 2204 deletions
diff --git a/TEST_MAPPING b/TEST_MAPPING
index 8f167cf47b..e5812efb4f 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -333,6 +333,9 @@
"name": "CtsStrictJavaPackagesTestCases"
},
{
+ "name": "net_test_bta_jv"
+ },
+ {
"name": "asrc_resampler_test"
}
]
diff --git a/android/app/jni/com_android_bluetooth_gatt.cpp b/android/app/jni/com_android_bluetooth_gatt.cpp
index aaf908a798..95a90f3c58 100644
--- a/android/app/jni/com_android_bluetooth_gatt.cpp
+++ b/android/app/jni/com_android_bluetooth_gatt.cpp
@@ -2827,10 +2827,10 @@ static int register_com_android_bluetooth_gatt_(JNIEnv* env) {
&method_onBatchScanThresholdCrossed},
{"createOnTrackAdvFoundLostObject",
"(II[BI[BIIILjava/lang/String;IIII)"
- "Lcom/android/bluetooth/gatt/AdvtFilterOnFoundOnLostInfo;",
+ "Lcom/android/bluetooth/le_scan/AdvtFilterOnFoundOnLostInfo;",
&method_createOnTrackAdvFoundLostObject},
{"onTrackAdvFoundLost",
- "(Lcom/android/bluetooth/gatt/AdvtFilterOnFoundOnLostInfo;)V",
+ "(Lcom/android/bluetooth/le_scan/AdvtFilterOnFoundOnLostInfo;)V",
&method_onTrackAdvFoundLost},
{"onScanParamSetupCompleted", "(II)V", &method_onScanParamSetupCompleted},
{"getSampleGattDbElement", "()Lcom/android/bluetooth/gatt/GattDbElement;",
diff --git a/android/app/src/com/android/bluetooth/gatt/CallbackInfo.java b/android/app/src/com/android/bluetooth/gatt/CallbackInfo.java
index ab3fe4ea4b..be01605b24 100644
--- a/android/app/src/com/android/bluetooth/gatt/CallbackInfo.java
+++ b/android/app/src/com/android/bluetooth/gatt/CallbackInfo.java
@@ -16,11 +16,12 @@
package com.android.bluetooth.gatt;
/**
- * Helper class that keeps track of callback parameters for app callbacks.
- * These are held during congestion and reported when congestion clears.
+ * Helper class that keeps track of callback parameters for app callbacks. These are held during
+ * congestion and reported when congestion clears.
+ *
* @hide
*/
-/* package */ class CallbackInfo {
+public class CallbackInfo {
public String address;
public int status;
public int handle;
diff --git a/android/app/src/com/android/bluetooth/gatt/ContextMap.java b/android/app/src/com/android/bluetooth/gatt/ContextMap.java
index 3457ed7e59..7492f8a139 100644
--- a/android/app/src/com/android/bluetooth/gatt/ContextMap.java
+++ b/android/app/src/com/android/bluetooth/gatt/ContextMap.java
@@ -18,6 +18,7 @@ package com.android.bluetooth.gatt;
import android.bluetooth.le.AdvertiseData;
import android.bluetooth.le.AdvertisingSetParameters;
import android.bluetooth.le.PeriodicAdvertisingParameters;
+import android.content.Context;
import android.os.Binder;
import android.os.IBinder;
import android.os.IInterface;
@@ -27,10 +28,11 @@ import android.os.UserHandle;
import android.os.WorkSource;
import android.util.Log;
-import androidx.annotation.VisibleForTesting;
import com.android.bluetooth.BluetoothMethodProxy;
import com.android.bluetooth.le_scan.AppScanStats;
+import com.android.bluetooth.le_scan.TransitionalScanHelper;
+import com.android.bluetooth.le_scan.TransitionalScanHelper.PendingIntentInfo;
import com.android.internal.annotations.GuardedBy;
import com.google.common.collect.EvictingQueue;
@@ -98,27 +100,27 @@ public class ContextMap<C, T> {
public Boolean isCongested = false;
/** Whether the calling app has location permission */
- boolean hasLocationPermission;
+ public boolean hasLocationPermission;
/** Whether the calling app has bluetooth privileged permission */
- boolean hasBluetoothPrivilegedPermission;
+ public boolean hasBluetoothPrivilegedPermission;
/** The user handle of the app that started the scan */
- UserHandle mUserHandle;
+ public UserHandle mUserHandle;
/** Whether the calling app has the network settings permission */
- boolean mHasNetworkSettingsPermission;
+ public boolean mHasNetworkSettingsPermission;
/** Whether the calling app has the network setup wizard permission */
- boolean mHasNetworkSetupWizardPermission;
+ public boolean mHasNetworkSetupWizardPermission;
/** Whether the calling app has the network setup wizard permission */
- boolean mHasScanWithoutLocationPermission;
+ public boolean mHasScanWithoutLocationPermission;
/** Whether the calling app has disavowed the use of bluetooth for location */
- boolean mHasDisavowedLocation;
+ public boolean mHasDisavowedLocation;
- boolean mEligibleForSanitizedExposureNotification;
+ public boolean mEligibleForSanitizedExposureNotification;
public List<String> mAssociatedDevices;
@@ -145,10 +147,8 @@ public class ContextMap<C, T> {
this.name = name;
}
- /**
- * Link death recipient
- */
- void linkToDeath(IBinder.DeathRecipient deathRecipient) {
+ /** Link death recipient */
+ public void linkToDeath(IBinder.DeathRecipient deathRecipient) {
// It might not be a binder object
if (callback == null) {
return;
@@ -162,10 +162,8 @@ public class ContextMap<C, T> {
}
}
- /**
- * Unlink death recipient
- */
- void unlinkToDeath() {
+ /** Unlink death recipient */
+ public void unlinkToDeath() {
if (mDeathRecipient != null) {
try {
IBinder binder = ((IInterface) callback).asBinder();
@@ -176,11 +174,11 @@ public class ContextMap<C, T> {
}
}
- void queueCallback(CallbackInfo callbackInfo) {
+ public void queueCallback(CallbackInfo callbackInfo) {
mCongestionQueue.add(callbackInfo);
}
- CallbackInfo popQueuedCallback() {
+ public CallbackInfo popQueuedCallback() {
if (mCongestionQueue.size() == 0) {
return null;
}
@@ -210,12 +208,13 @@ public class ContextMap<C, T> {
private final Object mConnectionsLock = new Object();
/** Add an entry to the application context list. */
- protected App add(
+ public App add(
UUID uuid,
WorkSource workSource,
C callback,
- GattService.PendingIntentInfo piInfo,
- GattService service) {
+ PendingIntentInfo piInfo,
+ Context context,
+ TransitionalScanHelper scanHelper) {
int appUid;
String appName = null;
if (piInfo != null) {
@@ -223,16 +222,18 @@ public class ContextMap<C, T> {
appName = piInfo.callingPackage;
} else {
appUid = Binder.getCallingUid();
- appName = service.getPackageManager().getNameForUid(appUid);
+ appName = context.getPackageManager().getNameForUid(appUid);
}
if (appName == null) {
// Assign an app name if one isn't found
appName = "Unknown App (UID: " + appUid + ")";
}
synchronized (mAppsLock) {
+ // TODO(b/327849650): AppScanStats appears to be only needed for the ScannerMap.
+ // Consider refactoring this.
AppScanStats appScanStats = mAppScanStats.get(appUid);
if (appScanStats == null) {
- appScanStats = new AppScanStats(appName, workSource, this, service);
+ appScanStats = new AppScanStats(appName, workSource, this, context, scanHelper);
mAppScanStats.put(appUid, appScanStats);
}
App app = new App(uuid, callback, (T) piInfo, appName, appScanStats);
@@ -242,10 +243,8 @@ public class ContextMap<C, T> {
}
}
- /**
- * Add an entry to the application context list for advertiser.
- */
- App add(int id, C callback, GattService service) {
+ /** Add an entry to the application context list for advertiser. */
+ public App add(int id, C callback, GattService service) {
int appUid = Binder.getCallingUid();
String appName = service.getPackageManager().getNameForUid(appUid);
if (appName == null) {
@@ -270,10 +269,8 @@ public class ContextMap<C, T> {
}
}
- /**
- * Remove the context for a given UUID
- */
- void remove(UUID uuid) {
+ /** Remove the context for a given UUID */
+ public void remove(UUID uuid) {
synchronized (mAppsLock) {
Iterator<App> i = mApps.iterator();
while (i.hasNext()) {
@@ -288,10 +285,8 @@ public class ContextMap<C, T> {
}
}
- /**
- * Remove the context for a given application ID.
- */
- protected void remove(int id) {
+ /** Remove the context for a given application ID. */
+ public void remove(int id) {
boolean find = false;
synchronized (mAppsLock) {
Iterator<App> i = mApps.iterator();
@@ -311,7 +306,7 @@ public class ContextMap<C, T> {
}
}
- protected List<Integer> getAllAppsIds() {
+ public List<Integer> getAllAppsIds() {
List<Integer> appIds = new ArrayList();
synchronized (mAppsLock) {
Iterator<App> i = mApps.iterator();
@@ -366,10 +361,8 @@ public class ContextMap<C, T> {
}
}
- /**
- * Get an application context by ID.
- */
- protected App getById(int id) {
+ /** Get an application context by ID. */
+ public App getById(int id) {
synchronized (mAppsLock) {
Iterator<App> i = mApps.iterator();
while (i.hasNext()) {
@@ -383,10 +376,8 @@ public class ContextMap<C, T> {
return null;
}
- /**
- * Get an application context by UUID.
- */
- protected App getByUuid(UUID uuid) {
+ /** Get an application context by UUID. */
+ public App getByUuid(UUID uuid) {
synchronized (mAppsLock) {
Iterator<App> i = mApps.iterator();
while (i.hasNext()) {
@@ -417,10 +408,8 @@ public class ContextMap<C, T> {
return null;
}
- /**
- * Get an application context by the context info object.
- */
- protected App getByContextInfo(T contextInfo) {
+ /** Get an application context by the context info object. */
+ public App getByContextInfo(T contextInfo) {
synchronized (mAppsLock) {
Iterator<App> i = mApps.iterator();
while (i.hasNext()) {
@@ -434,10 +423,8 @@ public class ContextMap<C, T> {
return null;
}
- /**
- * Get Logging info by ID
- */
- protected AppScanStats getAppScanStatsById(int id) {
+ /** Get Logging info by ID */
+ public AppScanStats getAppScanStatsById(int id) {
App temp = getById(id);
if (temp != null) {
return temp.appScanStats;
@@ -670,10 +657,8 @@ public class ContextMap<C, T> {
return currentConnections;
}
- /**
- * Erases all application context entries.
- */
- protected void clear() {
+ /** Erases all application context entries. */
+ public void clear() {
synchronized (mAppsLock) {
Iterator<App> i = mApps.iterator();
while (i.hasNext()) {
diff --git a/android/app/src/com/android/bluetooth/gatt/GattNativeInterface.java b/android/app/src/com/android/bluetooth/gatt/GattNativeInterface.java
index 9c8fa539d5..1167bea931 100644
--- a/android/app/src/com/android/bluetooth/gatt/GattNativeInterface.java
+++ b/android/app/src/com/android/bluetooth/gatt/GattNativeInterface.java
@@ -18,6 +18,8 @@ package com.android.bluetooth.gatt;
import android.os.RemoteException;
+import com.android.bluetooth.le_scan.AdvtFilterOnFoundOnLostInfo;
+import com.android.bluetooth.le_scan.TransitionalScanHelper;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
@@ -70,13 +72,24 @@ public class GattNativeInterface {
void onScanResult(int eventType, int addressType, String address, int primaryPhy,
int secondaryPhy, int advertisingSid, int txPower, int rssi, int periodicAdvInt,
byte[] advData, String originalAddress) {
- getGattService().onScanResult(eventType, addressType, address, primaryPhy, secondaryPhy,
- advertisingSid, txPower, rssi, periodicAdvInt, advData, originalAddress);
+ getTransitionalScanHelper()
+ .onScanResult(
+ eventType,
+ addressType,
+ address,
+ primaryPhy,
+ secondaryPhy,
+ advertisingSid,
+ txPower,
+ rssi,
+ periodicAdvInt,
+ advData,
+ originalAddress);
}
void onScannerRegistered(int status, int scannerId, long uuidLsb, long uuidMsb)
throws RemoteException {
- getGattService().onScannerRegistered(status, scannerId, uuidLsb, uuidMsb);
+ getTransitionalScanHelper().onScannerRegistered(status, scannerId, uuidLsb, uuidMsb);
}
void onClientRegistered(int status, int clientIf, long uuidLsb, long uuidMsb)
@@ -187,50 +200,65 @@ public class GattNativeInterface {
}
void onScanFilterEnableDisabled(int action, int status, int clientIf) {
- getGattService().onScanFilterEnableDisabled(action, status, clientIf);
+ getTransitionalScanHelper().onScanFilterEnableDisabled(action, status, clientIf);
}
void onScanFilterParamsConfigured(int action, int status, int clientIf, int availableSpace) {
- getGattService().onScanFilterParamsConfigured(action, status, clientIf, availableSpace);
+ getTransitionalScanHelper()
+ .onScanFilterParamsConfigured(action, status, clientIf, availableSpace);
}
void onScanFilterConfig(int action, int status, int clientIf, int filterType,
int availableSpace) {
- getGattService().onScanFilterConfig(action, status, clientIf, filterType, availableSpace);
+ getTransitionalScanHelper()
+ .onScanFilterConfig(action, status, clientIf, filterType, availableSpace);
}
void onBatchScanStorageConfigured(int status, int clientIf) {
- getGattService().onBatchScanStorageConfigured(status, clientIf);
+ getTransitionalScanHelper().onBatchScanStorageConfigured(status, clientIf);
}
void onBatchScanStartStopped(int startStopAction, int status, int clientIf) {
- getGattService().onBatchScanStartStopped(startStopAction, status, clientIf);
+ getTransitionalScanHelper().onBatchScanStartStopped(startStopAction, status, clientIf);
}
void onBatchScanReports(int status, int scannerId, int reportType, int numRecords,
byte[] recordData) throws RemoteException {
- getGattService().onBatchScanReports(status, scannerId, reportType, numRecords, recordData);
+ getTransitionalScanHelper()
+ .onBatchScanReports(status, scannerId, reportType, numRecords, recordData);
}
void onBatchScanThresholdCrossed(int clientIf) {
- getGattService().onBatchScanThresholdCrossed(clientIf);
+ getTransitionalScanHelper().onBatchScanThresholdCrossed(clientIf);
}
AdvtFilterOnFoundOnLostInfo createOnTrackAdvFoundLostObject(int clientIf, int advPktLen,
byte[] advPkt, int scanRspLen, byte[] scanRsp, int filtIndex, int advState,
int advInfoPresent, String address, int addrType, int txPower, int rssiValue,
int timeStamp) {
- return getGattService().createOnTrackAdvFoundLostObject(clientIf, advPktLen, advPkt,
- scanRspLen, scanRsp, filtIndex, advState, advInfoPresent, address, addrType,
- txPower, rssiValue, timeStamp);
+ return getTransitionalScanHelper()
+ .createOnTrackAdvFoundLostObject(
+ clientIf,
+ advPktLen,
+ advPkt,
+ scanRspLen,
+ scanRsp,
+ filtIndex,
+ advState,
+ advInfoPresent,
+ address,
+ addrType,
+ txPower,
+ rssiValue,
+ timeStamp);
}
void onTrackAdvFoundLost(AdvtFilterOnFoundOnLostInfo trackingInfo) throws RemoteException {
- getGattService().onTrackAdvFoundLost(trackingInfo);
+ getTransitionalScanHelper().onTrackAdvFoundLost(trackingInfo);
}
void onScanParamSetupCompleted(int status, int scannerId) throws RemoteException {
- getGattService().onScanParamSetupCompleted(status, scannerId);
+ getTransitionalScanHelper().onScanParamSetupCompleted(status, scannerId);
}
void onConfigureMTU(int connId, int status, int mtu) throws RemoteException {
@@ -665,5 +693,11 @@ public class GattNativeInterface {
int p1, int p2, int p3, int p4, int p5) {
gattTestNative(command, uuid1Lsb, uuid1Msb, bda1, p1, p2, p3, p4, p5);
}
+
+ // TODO(b/327849650): Callbacks that reference this helper should be moved into the appropriate
+ // native interface (ScanNativeInterface, PeriodicScanNativeInterface, etc.).
+ private TransitionalScanHelper getTransitionalScanHelper() {
+ return mGattService.getTransitionalScanHelper();
+ }
}
diff --git a/android/app/src/com/android/bluetooth/gatt/GattObjectsFactory.java b/android/app/src/com/android/bluetooth/gatt/GattObjectsFactory.java
index 3cc02b851b..0a02c2d142 100644
--- a/android/app/src/com/android/bluetooth/gatt/GattObjectsFactory.java
+++ b/android/app/src/com/android/bluetooth/gatt/GattObjectsFactory.java
@@ -16,6 +16,7 @@
package com.android.bluetooth.gatt;
+import android.content.Context;
import android.os.Looper;
import android.util.Log;
@@ -25,6 +26,7 @@ import com.android.bluetooth.btservice.BluetoothAdapterProxy;
import com.android.bluetooth.le_scan.PeriodicScanManager;
import com.android.bluetooth.le_scan.ScanManager;
import com.android.bluetooth.le_scan.ScanNativeInterface;
+import com.android.bluetooth.le_scan.TransitionalScanHelper;
/**
* Factory class for object initialization to help with unit testing
@@ -75,18 +77,20 @@ public class GattObjectsFactory {
/**
* Create an instance of ScanManager
*
- * @param service a GattService instance
+ * @param context a Context instance
+ * @param scanHelper a TransitionalScanHelper instance
* @param adapterService an AdapterService instance
* @param bluetoothAdapterProxy a bluetoothAdapterProxy instance
* @param looper the looper to be used for processing messages
* @return the created ScanManager instance
*/
public ScanManager createScanManager(
- GattService service,
+ Context context,
+ TransitionalScanHelper scanHelper,
AdapterService adapterService,
BluetoothAdapterProxy bluetoothAdapterProxy,
Looper looper) {
- return new ScanManager(service, adapterService, bluetoothAdapterProxy, looper);
+ return new ScanManager(context, scanHelper, adapterService, bluetoothAdapterProxy, looper);
}
public PeriodicScanManager createPeriodicScanManager(AdapterService adapterService) {
diff --git a/android/app/src/com/android/bluetooth/gatt/GattService.java b/android/app/src/com/android/bluetooth/gatt/GattService.java
index 4f4dab7325..690c841bdd 100644
--- a/android/app/src/com/android/bluetooth/gatt/GattService.java
+++ b/android/app/src/com/android/bluetooth/gatt/GattService.java
@@ -25,7 +25,6 @@ import static com.android.bluetooth.Utils.enforceBluetoothPrivilegedPermission;
import android.annotation.RequiresPermission;
import android.annotation.SuppressLint;
import android.app.ActivityManager;
-import android.app.AppOpsManager;
import android.app.PendingIntent;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
@@ -42,7 +41,6 @@ import android.bluetooth.IBluetoothGattCallback;
import android.bluetooth.IBluetoothGattServerCallback;
import android.bluetooth.le.AdvertiseData;
import android.bluetooth.le.AdvertisingSetParameters;
-import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ChannelSoundingParams;
import android.bluetooth.le.DistanceMeasurementMethod;
import android.bluetooth.le.DistanceMeasurementParams;
@@ -51,22 +49,15 @@ import android.bluetooth.le.IDistanceMeasurementCallback;
import android.bluetooth.le.IPeriodicAdvertisingCallback;
import android.bluetooth.le.IScannerCallback;
import android.bluetooth.le.PeriodicAdvertisingParameters;
-import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanFilter;
-import android.bluetooth.le.ScanRecord;
import android.bluetooth.le.ScanResult;
import android.bluetooth.le.ScanSettings;
-import android.companion.AssociationInfo;
-import android.companion.CompanionDeviceManager;
import android.content.AttributionSource;
import android.content.Context;
-import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.PackageManager.PackageInfoFlags;
import android.content.res.Resources;
-import android.net.MacAddress;
-import android.os.Binder;
import android.os.Build;
import android.os.Handler;
import android.os.HandlerThread;
@@ -74,10 +65,7 @@ import android.os.IBinder;
import android.os.Message;
import android.os.ParcelUuid;
import android.os.RemoteException;
-import android.os.SystemClock;
-import android.os.UserHandle;
import android.os.WorkSource;
-import android.provider.DeviceConfig;
import android.provider.Settings;
import android.sysprop.BluetoothProperties;
import android.text.format.DateUtils;
@@ -94,29 +82,20 @@ import com.android.bluetooth.btservice.CompanionManager;
import com.android.bluetooth.btservice.MetricsLogger;
import com.android.bluetooth.btservice.ProfileService;
import com.android.bluetooth.flags.Flags;
-import com.android.bluetooth.le_scan.AppScanStats;
-import com.android.bluetooth.le_scan.PeriodicScanManager;
-import com.android.bluetooth.le_scan.ScanClient;
-import com.android.bluetooth.le_scan.ScanManager;
import com.android.bluetooth.le_scan.TransitionalScanHelper;
-import com.android.bluetooth.util.NumberUtils;
import com.android.internal.annotations.VisibleForTesting;
import com.android.modules.utils.SynchronousResultReceiver;
import libcore.util.HexEncoding;
-import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
-import java.util.concurrent.TimeUnit;
-import java.util.function.Predicate;
/**
* Provides Bluetooth Gatt profile, as a service in
@@ -130,47 +109,7 @@ public class GattService extends ProfileService {
private static final String UUID_SUFFIX = "-0000-1000-8000-00805f9b34fb";
private static final String UUID_ZERO_PAD = "00000000";
- static final int SCAN_FILTER_ENABLED = 1;
- static final int SCAN_FILTER_MODIFIED = 2;
-
private static final int MAC_ADDRESS_LENGTH = 6;
- // Batch scan related constants.
- private static final int TRUNCATED_RESULT_SIZE = 11;
- private static final int TIME_STAMP_LENGTH = 2;
-
- private enum MatchOrigin {
- PSEUDO_ADDRESS,
- ORIGINAL_ADDRESS
- }
-
- private static class MatchResult {
- private final boolean mMatches;
- private final MatchOrigin mOrigin;
- private MatchResult(boolean matches, MatchOrigin origin) {
- this.mMatches = matches;
- this.mOrigin = origin;
- }
-
- public boolean getMatches() {
- return mMatches;
- }
-
- public MatchOrigin getMatchOrigin() {
- return mOrigin;
- }
- }
-
- /**
- * The default floor value for LE batch scan report delays greater than 0
- */
- @VisibleForTesting
- static final long DEFAULT_REPORT_DELAY_FLOOR = 5000;
-
- // onFoundLost related constants
- private static final int ADVT_STATE_ONFOUND = 0;
- private static final int ADVT_STATE_ONLOST = 1;
-
- private static final int ET_LEGACY_MASK = 0x10;
private static final UUID HID_SERVICE_UUID =
UUID.fromString("00001812-0000-1000-8000-00805F9B34FB");
@@ -209,34 +148,8 @@ public class GattService extends ProfileService {
"0201061AFF4C000215426C7565436861726D426561636F6E730EFE1355C509168020691E0EFE13551109426C7565436861726D5F31363936383500000000",
};
- /**
- * Keep the arguments passed in for the PendingIntent.
- */
- public static class PendingIntentInfo {
- public PendingIntent intent;
- public ScanSettings settings;
- public List<ScanFilter> filters;
- public String callingPackage;
- public int callingUid;
-
- @Override
- public boolean equals(Object other) {
- if (!(other instanceof PendingIntentInfo)) {
- return false;
- }
- return intent.equals(((PendingIntentInfo) other).intent);
- }
- }
-
- private final PendingIntent.CancelListener mScanIntentCancelListener =
- new PendingIntent.CancelListener(){
- public void onCanceled(PendingIntent intent) {
- Log.d(TAG, "scanning PendingIntent canceled");
- stopScan(intent, getAttributionSource());
- }
- };
-
- public final TransitionalScanHelper mTransitionalScanHelper = new TransitionalScanHelper();
+ public final TransitionalScanHelper mTransitionalScanHelper =
+ new TransitionalScanHelper(this, this::isTestModeEnabled);
/**
* List of our registered advertisers.
@@ -265,16 +178,6 @@ public class GattService extends ProfileService {
HandleMap mHandleMap = new HandleMap();
private List<UUID> mAdvertisingServiceUuids = new ArrayList<UUID>();
- private int mMaxScanFilters;
-
- private static final int NUM_SCAN_EVENTS_KEPT = 20;
-
- /**
- * Internal list of scan events to use with the proto
- */
- private final ArrayDeque<BluetoothMetricsProto.ScanEvent> mScanEvents =
- new ArrayDeque<>(NUM_SCAN_EVENTS_KEPT);
-
/**
* Set of restricted (which require a BLUETOOTH_PRIVILEGED permission) handles per connectionId.
*/
@@ -289,12 +192,7 @@ public class GattService extends ProfileService {
private AdapterService mAdapterService;
private BluetoothAdapterProxy mBluetoothAdapterProxy;
AdvertiseManager mAdvertiseManager;
- PeriodicScanManager mPeriodicScanManager;
DistanceMeasurementManager mDistanceMeasurementManager;
- ScanManager mScanManager;
- private AppOpsManager mAppOps;
- private CompanionDeviceManager mCompanionManager;
- private String mExposureNotificationPackage;
private Handler mTestModeHandler;
private ActivityManager mActivityManager;
private PackageManager mPackageManager;
@@ -309,23 +207,6 @@ public class GattService extends ProfileService {
}
/**
- */
- private final Predicate<ScanResult> mLocationDenylistPredicate = (scanResult) -> {
- final MacAddress parsedAddress = MacAddress
- .fromString(scanResult.getDevice().getAddress());
- if (mAdapterService.getLocationDenylistMac().test(parsedAddress.toByteArray())) {
- Log.v(TAG, "Skipping device matching denylist: " + scanResult.getDevice());
- return true;
- }
- final ScanRecord scanRecord = scanResult.getScanRecord();
- if (scanRecord.matchesAnyField(mAdapterService.getLocationDenylistAdvertisingData())) {
- Log.v(TAG, "Skipping data matching denylist: " + scanRecord);
- return true;
- }
- return false;
- };
-
- /**
* Reliable write queue
*/
@VisibleForTesting
@@ -343,7 +224,6 @@ public class GattService extends ProfileService {
if (DBG) {
Log.d(TAG, "start()");
}
- mExposureNotificationPackage = getString(R.string.exposure_notification_package);
Settings.Global.putInt(
getContentResolver(), "bluetooth_sanitized_exposure_notification_supported", 1);
@@ -351,8 +231,6 @@ public class GattService extends ProfileService {
mNativeInterface.init(this);
mAdapterService = AdapterService.getAdapterService();
mBluetoothAdapterProxy = BluetoothAdapterProxy.getInstance();
- mCompanionManager = getSystemService(CompanionDeviceManager.class);
- mAppOps = getSystemService(AppOpsManager.class);
mAdvertiseManager =
new AdvertiseManager(
this,
@@ -362,14 +240,7 @@ public class GattService extends ProfileService {
HandlerThread thread = new HandlerThread("BluetoothScanManager");
thread.start();
- mScanManager =
- GattObjectsFactory.getInstance()
- .createScanManager(
- this, mAdapterService, mBluetoothAdapterProxy, thread.getLooper());
-
- mPeriodicScanManager = GattObjectsFactory.getInstance()
- .createPeriodicScanManager(mAdapterService);
-
+ mTransitionalScanHelper.start(thread.getLooper());
mDistanceMeasurementManager = GattObjectsFactory.getInstance()
.createDistanceMeasurementManager(mAdapterService);
@@ -382,7 +253,7 @@ public class GattService extends ProfileService {
if (DBG) {
Log.d(TAG, "stop()");
}
- mTransitionalScanHelper.getScannerMap().clear();
+ mTransitionalScanHelper.stop();
mAdvertiserMap.clear();
mClientMap.clear();
if (Flags.gattCleanupRestrictedHandles()) {
@@ -406,15 +277,14 @@ public class GattService extends ProfileService {
if (mAdvertiseManager != null) {
mAdvertiseManager.cleanup();
}
- if (mScanManager != null) {
- mScanManager.cleanup();
- }
- if (mPeriodicScanManager != null) {
- mPeriodicScanManager.cleanup();
- }
if (mDistanceMeasurementManager != null) {
mDistanceMeasurementManager.cleanup();
}
+ mTransitionalScanHelper.cleanup();
+ }
+
+ TransitionalScanHelper getTransitionalScanHelper() {
+ return mTransitionalScanHelper;
}
// While test mode is enabled, pretend as if the underlying stack
@@ -423,21 +293,31 @@ public class GattService extends ProfileService {
protected void setTestModeEnabled(boolean enableTestMode) {
synchronized (mTestModeLock) {
if (mTestModeHandler == null) {
- mTestModeHandler = new Handler(getMainLooper()) {
- public void handleMessage(Message msg) {
- synchronized (mTestModeLock) {
- if (!GattService.this.isTestModeEnabled()) {
- return;
+ mTestModeHandler =
+ new Handler(getMainLooper()) {
+ public void handleMessage(Message msg) {
+ synchronized (mTestModeLock) {
+ if (!GattService.this.isTestModeEnabled()) {
+ return;
+ }
+ for (String test : TEST_MODE_BEACONS) {
+ mTransitionalScanHelper.onScanResultInternal(
+ 0x1b,
+ 0x1,
+ "DD:34:02:05:5C:4D",
+ 1,
+ 0,
+ 0xff,
+ 127,
+ -54,
+ 0x0,
+ HexEncoding.decode(test),
+ "DD:34:02:05:5C:4E");
+ }
+ sendEmptyMessageDelayed(0, DateUtils.SECOND_IN_MILLIS);
+ }
}
- for (String test : TEST_MODE_BEACONS) {
- onScanResultInternal(0x1b, 0x1, "DD:34:02:05:5C:4D", 1, 0, 0xff,
- 127, -54, 0x0, HexEncoding.decode(test),
- "DD:34:02:05:5C:4E");
- }
- sendEmptyMessageDelayed(0, DateUtils.SECOND_IN_MILLIS);
- }
- }
- };
+ };
}
if (enableTestMode && !isTestModeEnabled()) {
super.setTestModeEnabled(true);
@@ -451,15 +331,6 @@ public class GattService extends ProfileService {
}
}
- @VisibleForTesting
- ScanManager getScanManager() {
- if (mScanManager == null) {
- Log.w(TAG, "getScanManager(): scan manager is null");
- return null;
- }
- return mScanManager;
- }
-
// Suppressed because we are conditionally enforcing
@SuppressLint("AndroidFrameworkRequiresPermission")
private void permissionCheck(UUID characteristicUuid) {
@@ -495,63 +366,7 @@ public class GattService extends ProfileService {
/** Notify Scan manager of bluetooth profile connection state changes */
public void notifyProfileConnectionStateChange(int profile, int fromState, int toState) {
- if (mScanManager == null) {
- Log.w(TAG, "scan manager is null");
- return;
- }
- mScanManager.handleBluetoothProfileConnectionStateChanged(profile, fromState, toState);
- }
-
- /**
- * DeathReceipient handlers used to unregister applications that
- * disconnect ungracefully (ie. crash or forced close).
- */
-
- class ScannerDeathRecipient implements IBinder.DeathRecipient {
- int mScannerId;
- private String mPackageName;
-
- ScannerDeathRecipient(int scannerId, String packageName) {
- mScannerId = scannerId;
- mPackageName = packageName;
- }
-
- @Override
- public void binderDied() {
- if (DBG) {
- Log.d(
- TAG,
- "Binder is dead - unregistering scanner ("
- + mPackageName
- + " "
- + mScannerId
- + ")!");
- }
-
- ScanClient client = getScanClient(mScannerId);
- if (client != null) {
- if (Flags.leScanFixRemoteException()) {
- handleDeadScanClient(client);
- } else {
- client.appDied = true;
- stopScan(client.scannerId, getAttributionSource());
- }
- }
- }
-
- private ScanClient getScanClient(int clientIf) {
- for (ScanClient client : mScanManager.getRegularScanQueue()) {
- if (client.scannerId == clientIf) {
- return client;
- }
- }
- for (ScanClient client : mScanManager.getBatchScanQueue()) {
- if (client.scannerId == clientIf) {
- return client;
- }
- }
- return null;
- }
+ mTransitionalScanHelper.notifyProfileConnectionStateChange(profile, fromState, toState);
}
class ServerDeathRecipient implements IBinder.DeathRecipient {
@@ -700,7 +515,8 @@ public class GattService extends ProfileService {
if (service == null) {
return;
}
- service.registerScanner(callback, workSource, attributionSource);
+ service.getTransitionalScanHelper()
+ .registerScanner(callback, workSource, attributionSource);
}
@Override
@@ -718,7 +534,7 @@ public class GattService extends ProfileService {
if (service == null) {
return;
}
- service.unregisterScanner(scannerId, attributionSource);
+ service.getTransitionalScanHelper().unregisterScanner(scannerId, attributionSource);
}
@Override
@@ -738,7 +554,8 @@ public class GattService extends ProfileService {
if (service == null) {
return;
}
- service.startScan(scannerId, settings, filters, attributionSource);
+ service.getTransitionalScanHelper()
+ .startScan(scannerId, settings, filters, attributionSource);
}
@Override
@@ -761,7 +578,8 @@ public class GattService extends ProfileService {
if (service == null) {
return;
}
- service.registerPiAndStartScan(intent, settings, filters, attributionSource);
+ service.getTransitionalScanHelper()
+ .registerPiAndStartScan(intent, settings, filters, attributionSource);
}
@Override
@@ -780,7 +598,7 @@ public class GattService extends ProfileService {
if (service == null) {
return;
}
- service.stopScan(intent, attributionSource);
+ service.getTransitionalScanHelper().stopScan(intent, attributionSource);
}
@Override
@@ -798,7 +616,7 @@ public class GattService extends ProfileService {
if (service == null) {
return;
}
- service.stopScan(scannerId, attributionSource);
+ service.getTransitionalScanHelper().stopScan(scannerId, attributionSource);
}
@Override
@@ -816,7 +634,8 @@ public class GattService extends ProfileService {
if (service == null) {
return;
}
- service.flushPendingBatchResults(scannerId, attributionSource);
+ service.getTransitionalScanHelper()
+ .flushPendingBatchResults(scannerId, attributionSource);
}
@Override
@@ -1686,7 +1505,8 @@ public class GattService extends ProfileService {
if (service == null) {
return;
}
- service.registerSync(scanResult, skip, timeout, callback, attributionSource);
+ service.getTransitionalScanHelper()
+ .registerSync(scanResult, skip, timeout, callback, attributionSource);
}
@Override
@@ -1705,7 +1525,8 @@ public class GattService extends ProfileService {
if (service == null) {
return;
}
- service.transferSync(bda, serviceData , syncHandle, attributionSource);
+ service.getTransitionalScanHelper()
+ .transferSync(bda, serviceData, syncHandle, attributionSource);
}
@Override
@@ -1725,7 +1546,8 @@ public class GattService extends ProfileService {
if (service == null) {
return;
}
- service.transferSetInfo(bda, serviceData , advHandle, callback, attributionSource);
+ service.getTransitionalScanHelper()
+ .transferSetInfo(bda, serviceData, advHandle, callback, attributionSource);
}
@Override
@@ -1744,7 +1566,7 @@ public class GattService extends ProfileService {
if (service == null) {
return;
}
- service.unregisterSync(callback, attributionSource);
+ service.getTransitionalScanHelper().unregisterSync(callback, attributionSource);
}
@Override
@@ -1922,302 +1744,6 @@ public class GattService extends ProfileService {
* Callback functions - CLIENT
*************************************************************************/
- // EN format defined here:
- // https://blog.google/documents/70/Exposure_Notification_-_Bluetooth_Specification_v1.2.2.pdf
- private static final byte[] EXPOSURE_NOTIFICATION_FLAGS_PREAMBLE = new byte[] {
- // size 2, flag field, flags byte (value is not important)
- (byte) 0x02, (byte) 0x01
- };
- private static final int EXPOSURE_NOTIFICATION_FLAGS_LENGTH = 0x2 + 1;
- private static final byte[] EXPOSURE_NOTIFICATION_PAYLOAD_PREAMBLE = new byte[] {
- // size 3, complete 16 bit UUID, EN UUID
- (byte) 0x03, (byte) 0x03, (byte) 0x6F, (byte) 0xFD,
- // size 23, data for 16 bit UUID, EN UUID
- (byte) 0x17, (byte) 0x16, (byte) 0x6F, (byte) 0xFD,
- // ...payload
- };
- private static final int EXPOSURE_NOTIFICATION_PAYLOAD_LENGTH = 0x03 + 0x17 + 2;
-
- private static boolean arrayStartsWith(byte[] array, byte[] prefix) {
- if (array.length < prefix.length) {
- return false;
- }
- for (int i = 0; i < prefix.length; i++) {
- if (prefix[i] != array[i]) {
- return false;
- }
- }
- return true;
- }
-
- ScanResult getSanitizedExposureNotification(ScanResult result) {
- ScanRecord record = result.getScanRecord();
- // Remove the flags part of the payload, if present
- if (record.getBytes().length > EXPOSURE_NOTIFICATION_FLAGS_LENGTH
- && arrayStartsWith(record.getBytes(), EXPOSURE_NOTIFICATION_FLAGS_PREAMBLE)) {
- record = ScanRecord.parseFromBytes(
- Arrays.copyOfRange(
- record.getBytes(),
- EXPOSURE_NOTIFICATION_FLAGS_LENGTH,
- record.getBytes().length));
- }
-
- if (record.getBytes().length != EXPOSURE_NOTIFICATION_PAYLOAD_LENGTH) {
- return null;
- }
- if (!arrayStartsWith(record.getBytes(), EXPOSURE_NOTIFICATION_PAYLOAD_PREAMBLE)) {
- return null;
- }
-
- return new ScanResult(null, 0, 0, 0, 0, 0, result.getRssi(), 0, record, 0);
- }
-
- void onScanResult(int eventType, int addressType, String address, int primaryPhy,
- int secondaryPhy, int advertisingSid, int txPower, int rssi, int periodicAdvInt,
- byte[] advData, String originalAddress) {
- // When in testing mode, ignore all real-world events
- if (isTestModeEnabled()) return;
-
- AppScanStats.recordScanRadioResultCount();
- onScanResultInternal(eventType, addressType, address, primaryPhy, secondaryPhy,
- advertisingSid, txPower, rssi, periodicAdvInt, advData, originalAddress);
- }
-
- void onScanResultInternal(int eventType, int addressType, String address, int primaryPhy,
- int secondaryPhy, int advertisingSid, int txPower, int rssi, int periodicAdvInt,
- byte[] advData, String originalAddress) {
- if (VDBG) {
- Log.d(TAG, "onScanResult() - eventType=0x" + Integer.toHexString(eventType)
- + ", addressType=" + addressType + ", address=" + address + ", primaryPhy="
- + primaryPhy + ", secondaryPhy=" + secondaryPhy + ", advertisingSid=0x"
- + Integer.toHexString(advertisingSid) + ", txPower=" + txPower + ", rssi="
- + rssi + ", periodicAdvInt=0x" + Integer.toHexString(periodicAdvInt)
- + ", originalAddress=" + originalAddress);
- }
-
- String identityAddress = mAdapterService.getIdentityAddress(address);
- if (!address.equals(identityAddress)) {
- if (VDBG) {
- Log.d(TAG, "found identityAddress of " + address + ", replace originalAddress as "
- + identityAddress);
- }
- originalAddress = identityAddress;
- }
-
-
- byte[] legacyAdvData = Arrays.copyOfRange(advData, 0, 62);
-
- for (ScanClient client : mScanManager.getRegularScanQueue()) {
- TransitionalScanHelper.ScannerMap.App app =
- mTransitionalScanHelper.getScannerMap().getById(client.scannerId);
- if (app == null) {
- if (VDBG) {
- Log.d(TAG, "App is null; skip.");
- }
- continue;
- }
-
- BluetoothDevice device =
- BluetoothAdapter.getDefaultAdapter().getRemoteLeDevice(address, addressType);
-
- ScanSettings settings = client.settings;
- byte[] scanRecordData;
- // This is for compability with applications that assume fixed size scan data.
- if (settings.getLegacy()) {
- if ((eventType & ET_LEGACY_MASK) == 0) {
- // If this is legacy scan, but nonlegacy result - skip.
- if (VDBG) {
- Log.d(TAG, "Legacy scan, non legacy result; skip.");
- }
- continue;
- } else {
- // Some apps are used to fixed-size advertise data.
- scanRecordData = legacyAdvData;
- }
- } else {
- scanRecordData = advData;
- }
-
- ScanRecord scanRecord = ScanRecord.parseFromBytes(scanRecordData);
- ScanResult result =
- new ScanResult(device, eventType, primaryPhy, secondaryPhy, advertisingSid,
- txPower, rssi, periodicAdvInt, scanRecord,
- SystemClock.elapsedRealtimeNanos());
-
- if (client.hasDisavowedLocation) {
- if (mLocationDenylistPredicate.test(result)) {
- Log.i(TAG, "Skipping client for location deny list");
- continue;
- }
- }
-
- boolean hasPermission = hasScanResultPermission(client);
- if (!hasPermission) {
- for (String associatedDevice : client.associatedDevices) {
- if (associatedDevice.equalsIgnoreCase(address)) {
- hasPermission = true;
- break;
- }
- }
- }
- if (!hasPermission && client.eligibleForSanitizedExposureNotification) {
- ScanResult sanitized = getSanitizedExposureNotification(result);
- if (sanitized != null) {
- hasPermission = true;
- result = sanitized;
- }
- }
- MatchResult matchResult = matchesFilters(client, result, originalAddress);
- if (!hasPermission || !matchResult.getMatches()) {
- if (VDBG) {
- Log.d(TAG, "Skipping client: permission="
- + hasPermission + " matches=" + matchResult.getMatches());
- }
- continue;
- }
-
- int callbackType = settings.getCallbackType();
- if (!(callbackType == ScanSettings.CALLBACK_TYPE_ALL_MATCHES
- || callbackType == ScanSettings.CALLBACK_TYPE_ALL_MATCHES_AUTO_BATCH)) {
- if (VDBG) {
- Log.d(TAG, "Skipping client: CALLBACK_TYPE_ALL_MATCHES");
- }
- continue;
- }
-
- try {
- app.appScanStats.addResult(client.scannerId);
- if (app.callback != null) {
- app.callback.onScanResult(result);
- } else {
- // Send the PendingIntent
- ArrayList<ScanResult> results = new ArrayList<>();
- results.add(result);
- sendResultsByPendingIntent(app.info, results,
- ScanSettings.CALLBACK_TYPE_ALL_MATCHES);
- }
- } catch (RemoteException | PendingIntent.CanceledException e) {
- Log.e(TAG, "Exception: " + e);
- if (Flags.leScanFixRemoteException()) {
- handleDeadScanClient(client);
- } else {
- mTransitionalScanHelper.getScannerMap().remove(client.scannerId);
- mScanManager.stopScan(client.scannerId);
- }
- }
- }
- }
-
- private void sendResultByPendingIntent(PendingIntentInfo pii, ScanResult result,
- int callbackType, ScanClient client) {
- ArrayList<ScanResult> results = new ArrayList<>();
- results.add(result);
- try {
- sendResultsByPendingIntent(pii, results, callbackType);
- } catch (PendingIntent.CanceledException e) {
- final long token = Binder.clearCallingIdentity();
- try {
- stopScan(client.scannerId, getAttributionSource());
- unregisterScanner(client.scannerId, getAttributionSource());
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
- }
-
- private void sendResultsByPendingIntent(PendingIntentInfo pii, ArrayList<ScanResult> results,
- int callbackType) throws PendingIntent.CanceledException {
- Intent extrasIntent = new Intent();
- extrasIntent.putParcelableArrayListExtra(BluetoothLeScanner.EXTRA_LIST_SCAN_RESULT,
- results);
- extrasIntent.putExtra(BluetoothLeScanner.EXTRA_CALLBACK_TYPE, callbackType);
- pii.intent.send(this, 0, extrasIntent);
- }
-
- private void sendErrorByPendingIntent(PendingIntentInfo pii, int errorCode)
- throws PendingIntent.CanceledException {
- Intent extrasIntent = new Intent();
- extrasIntent.putExtra(BluetoothLeScanner.EXTRA_ERROR_CODE, errorCode);
- pii.intent.send(this, 0, extrasIntent);
- }
-
- void onScannerRegistered(int status, int scannerId, long uuidLsb, long uuidMsb)
- throws RemoteException {
- UUID uuid = new UUID(uuidMsb, uuidLsb);
- if (DBG) {
- Log.d(TAG, "onScannerRegistered() - UUID=" + uuid + ", scannerId=" + scannerId
- + ", status=" + status);
- }
-
- // First check the callback map
- TransitionalScanHelper.ScannerMap.App cbApp =
- mTransitionalScanHelper.getScannerMap().getByUuid(uuid);
- if (cbApp != null) {
- if (status == 0) {
- cbApp.id = scannerId;
- // If app is callback based, setup a death recipient. App will initiate the start.
- // Otherwise, if PendingIntent based, start the scan directly.
- if (cbApp.callback != null) {
- cbApp.linkToDeath(new ScannerDeathRecipient(scannerId, cbApp.name));
- } else {
- continuePiStartScan(scannerId, cbApp);
- }
- } else {
- mTransitionalScanHelper.getScannerMap().remove(scannerId);
- }
- if (cbApp.callback != null) {
- cbApp.callback.onScannerRegistered(status, scannerId);
- }
- }
- }
-
- /** Determines if the given scan client has the appropriate permissions to receive callbacks. */
- private boolean hasScanResultPermission(final ScanClient client) {
- if (client.hasNetworkSettingsPermission
- || client.hasNetworkSetupWizardPermission
- || client.hasScanWithoutLocationPermission) {
- return true;
- }
- if (client.hasDisavowedLocation) {
- return true;
- }
- return client.hasLocationPermission && !Utils.blockedByLocationOff(this, client.userHandle);
- }
-
- // Check if a scan record matches a specific filters.
- private MatchResult matchesFilters(ScanClient client, ScanResult scanResult) {
- return matchesFilters(client, scanResult, null);
- }
-
- // Check if a scan record matches a specific filters or original address
- private MatchResult matchesFilters(ScanClient client, ScanResult scanResult,
- String originalAddress) {
- if (client.filters == null || client.filters.isEmpty()) {
- // TODO: Do we really wanna return true here?
- return new MatchResult(true, MatchOrigin.PSEUDO_ADDRESS);
- }
- for (ScanFilter filter : client.filters) {
- // Need to check the filter matches, and the original address without changing the API
- if (filter.matches(scanResult)) {
- return new MatchResult(true, MatchOrigin.PSEUDO_ADDRESS);
- }
- if (originalAddress != null
- && originalAddress.equalsIgnoreCase(filter.getDeviceAddress())) {
- return new MatchResult(true, MatchOrigin.ORIGINAL_ADDRESS);
- }
- }
- return new MatchResult(false, MatchOrigin.PSEUDO_ADDRESS);
- }
-
- private void handleDeadScanClient(ScanClient client) {
- if (client.appDied) {
- Log.w(TAG, "Already dead client " + client.scannerId);
- return;
- }
- client.appDied = true;
- stopScan(client.scannerId, getAttributionSource());
- }
-
void onClientRegistered(int status, int clientIf, long uuidLsb, long uuidMsb)
throws RemoteException {
UUID uuid = new UUID(uuidMsb, uuidLsb);
@@ -2719,404 +2245,6 @@ public class GattService extends ProfileService {
}
}
- void onScanFilterEnableDisabled(int action, int status, int clientIf) {
- if (DBG) {
- Log.d(TAG, "onScanFilterEnableDisabled() - clientIf=" + clientIf + ", status=" + status
- + ", action=" + action);
- }
- mScanManager.callbackDone(clientIf, status);
- }
-
- void onScanFilterParamsConfigured(int action, int status, int clientIf, int availableSpace) {
- if (DBG) {
- Log.d(TAG,
- "onScanFilterParamsConfigured() - clientIf=" + clientIf + ", status=" + status
- + ", action=" + action + ", availableSpace=" + availableSpace);
- }
- mScanManager.callbackDone(clientIf, status);
- }
-
- void onScanFilterConfig(int action, int status, int clientIf, int filterType,
- int availableSpace) {
- if (DBG) {
- Log.d(TAG, "onScanFilterConfig() - clientIf=" + clientIf + ", action = " + action
- + " status = " + status + ", filterType=" + filterType + ", availableSpace="
- + availableSpace);
- }
-
- mScanManager.callbackDone(clientIf, status);
- }
-
- void onBatchScanStorageConfigured(int status, int clientIf) {
- if (DBG) {
- Log.d(TAG,
- "onBatchScanStorageConfigured() - clientIf=" + clientIf + ", status=" + status);
- }
- mScanManager.callbackDone(clientIf, status);
- }
-
- // TODO: split into two different callbacks : onBatchScanStarted and onBatchScanStopped.
- void onBatchScanStartStopped(int startStopAction, int status, int clientIf) {
- if (DBG) {
- Log.d(TAG, "onBatchScanStartStopped() - clientIf=" + clientIf + ", status=" + status
- + ", startStopAction=" + startStopAction);
- }
- mScanManager.callbackDone(clientIf, status);
- }
-
- ScanClient findBatchScanClientById(int scannerId) {
- for (ScanClient client : mScanManager.getBatchScanQueue()) {
- if (client.scannerId == scannerId) {
- return client;
- }
- }
- return null;
- }
-
- void onBatchScanReports(int status, int scannerId, int reportType, int numRecords,
- byte[] recordData) throws RemoteException {
- // When in testing mode, ignore all real-world events
- if (isTestModeEnabled()) return;
-
- AppScanStats.recordBatchScanRadioResultCount(numRecords);
- onBatchScanReportsInternal(status, scannerId, reportType, numRecords, recordData);
- }
-
- void onBatchScanReportsInternal(int status, int scannerId, int reportType, int numRecords,
- byte[] recordData) throws RemoteException {
- if (DBG) {
- Log.d(TAG, "onBatchScanReports() - scannerId=" + scannerId + ", status=" + status
- + ", reportType=" + reportType + ", numRecords=" + numRecords);
- }
-
- Set<ScanResult> results = parseBatchScanResults(numRecords, reportType, recordData);
- if (reportType == ScanManager.SCAN_RESULT_TYPE_TRUNCATED) {
- // We only support single client for truncated mode.
- TransitionalScanHelper.ScannerMap.App app =
- mTransitionalScanHelper.getScannerMap().getById(scannerId);
- if (app == null) {
- return;
- }
-
- ScanClient client = findBatchScanClientById(scannerId);
- if (client == null) {
- return;
- }
-
- ArrayList<ScanResult> permittedResults;
- if (hasScanResultPermission(client)) {
- permittedResults = new ArrayList<ScanResult>(results);
- } else {
- permittedResults = new ArrayList<ScanResult>();
- for (ScanResult scanResult : results) {
- for (String associatedDevice : client.associatedDevices) {
- if (associatedDevice.equalsIgnoreCase(scanResult.getDevice()
- .getAddress())) {
- permittedResults.add(scanResult);
- }
- }
- }
- if (permittedResults.isEmpty()) {
- return;
- }
- }
-
- if (client.hasDisavowedLocation) {
- permittedResults.removeIf(mLocationDenylistPredicate);
- }
-
- if (app.callback != null) {
- app.callback.onBatchScanResults(permittedResults);
- } else {
- // PendingIntent based
- try {
- sendResultsByPendingIntent(app.info, permittedResults,
- ScanSettings.CALLBACK_TYPE_ALL_MATCHES);
- } catch (PendingIntent.CanceledException e) {
- }
- }
- } else {
- for (ScanClient client : mScanManager.getFullBatchScanQueue()) {
- // Deliver results for each client.
- deliverBatchScan(client, results);
- }
- }
- mScanManager.callbackDone(scannerId, status);
- }
-
- private void sendBatchScanResults(TransitionalScanHelper.ScannerMap.App app, ScanClient client,
- ArrayList<ScanResult> results) {
- try {
- if (app.callback != null) {
- if (mScanManager.isAutoBatchScanClientEnabled(client)) {
- if (DBG) {
- Log.d(TAG, "sendBatchScanResults() to onScanResult()" + client);
- }
- for (ScanResult result : results) {
- app.appScanStats.addResult(client.scannerId);
- app.callback.onScanResult(result);
- }
- } else {
- if (DBG) {
- Log.d(TAG, "sendBatchScanResults() to onBatchScanResults()" + client);
- }
- app.callback.onBatchScanResults(results);
- }
- } else {
- sendResultsByPendingIntent(app.info, results,
- ScanSettings.CALLBACK_TYPE_ALL_MATCHES);
- }
- } catch (RemoteException | PendingIntent.CanceledException e) {
- Log.e(TAG, "Exception: " + e);
- if (Flags.leScanFixRemoteException()) {
- handleDeadScanClient(client);
- } else {
- mTransitionalScanHelper.getScannerMap().remove(client.scannerId);
- mScanManager.stopScan(client.scannerId);
- }
- }
- }
-
- // Check and deliver scan results for different scan clients.
- private void deliverBatchScan(ScanClient client, Set<ScanResult> allResults)
- throws RemoteException {
- ContextMap.App app = mTransitionalScanHelper.getScannerMap().getById(client.scannerId);
- if (app == null) {
- return;
- }
-
- ArrayList<ScanResult> permittedResults;
- if (hasScanResultPermission(client)) {
- permittedResults = new ArrayList<ScanResult>(allResults);
- } else {
- permittedResults = new ArrayList<ScanResult>();
- for (ScanResult scanResult : allResults) {
- for (String associatedDevice : client.associatedDevices) {
- if (associatedDevice.equalsIgnoreCase(scanResult.getDevice().getAddress())) {
- permittedResults.add(scanResult);
- }
- }
- }
- if (permittedResults.isEmpty()) {
- return;
- }
- }
-
- if (client.filters == null || client.filters.isEmpty()) {
- sendBatchScanResults(app, client, permittedResults);
- // TODO: Question to reviewer: Shouldn't there be a return here?
- }
- // Reconstruct the scan results.
- ArrayList<ScanResult> results = new ArrayList<ScanResult>();
- for (ScanResult scanResult : permittedResults) {
- if (matchesFilters(client, scanResult).getMatches()) {
- results.add(scanResult);
- }
- }
- sendBatchScanResults(app, client, results);
- }
-
- private Set<ScanResult> parseBatchScanResults(int numRecords, int reportType,
- byte[] batchRecord) {
- if (numRecords == 0) {
- return Collections.emptySet();
- }
- if (DBG) {
- Log.d(TAG, "current time is " + SystemClock.elapsedRealtimeNanos());
- }
- if (reportType == ScanManager.SCAN_RESULT_TYPE_TRUNCATED) {
- return parseTruncatedResults(numRecords, batchRecord);
- } else {
- return parseFullResults(numRecords, batchRecord);
- }
- }
-
- private Set<ScanResult> parseTruncatedResults(int numRecords, byte[] batchRecord) {
- if (DBG) {
- Log.d(TAG, "batch record " + Arrays.toString(batchRecord));
- }
- Set<ScanResult> results = new HashSet<ScanResult>(numRecords);
- long now = SystemClock.elapsedRealtimeNanos();
- for (int i = 0; i < numRecords; ++i) {
- byte[] record =
- extractBytes(batchRecord, i * TRUNCATED_RESULT_SIZE, TRUNCATED_RESULT_SIZE);
- byte[] address = extractBytes(record, 0, 6);
- reverse(address);
- BluetoothDevice device = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(address);
- int rssi = record[8];
- long timestampNanos = now - parseTimestampNanos(extractBytes(record, 9, 2));
- results.add(new ScanResult(device, ScanRecord.parseFromBytes(new byte[0]), rssi,
- timestampNanos));
- }
- return results;
- }
-
- @VisibleForTesting
- long parseTimestampNanos(byte[] data) {
- long timestampUnit = NumberUtils.littleEndianByteArrayToInt(data);
- // Timestamp is in every 50 ms.
- return TimeUnit.MILLISECONDS.toNanos(timestampUnit * 50);
- }
-
- private Set<ScanResult> parseFullResults(int numRecords, byte[] batchRecord) {
- if (DBG) {
- Log.d(TAG, "Batch record : " + Arrays.toString(batchRecord));
- }
- Set<ScanResult> results = new HashSet<ScanResult>(numRecords);
- int position = 0;
- long now = SystemClock.elapsedRealtimeNanos();
- while (position < batchRecord.length) {
- byte[] address = extractBytes(batchRecord, position, 6);
- // TODO: remove temp hack.
- reverse(address);
- BluetoothDevice device = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(address);
- position += 6;
- // Skip address type.
- position++;
- // Skip tx power level.
- position++;
- int rssi = batchRecord[position++];
- long timestampNanos = now - parseTimestampNanos(extractBytes(batchRecord, position, 2));
- position += 2;
-
- // Combine advertise packet and scan response packet.
- int advertisePacketLen = batchRecord[position++];
- byte[] advertiseBytes = extractBytes(batchRecord, position, advertisePacketLen);
- position += advertisePacketLen;
- int scanResponsePacketLen = batchRecord[position++];
- byte[] scanResponseBytes = extractBytes(batchRecord, position, scanResponsePacketLen);
- position += scanResponsePacketLen;
- byte[] scanRecord = new byte[advertisePacketLen + scanResponsePacketLen];
- System.arraycopy(advertiseBytes, 0, scanRecord, 0, advertisePacketLen);
- System.arraycopy(scanResponseBytes, 0, scanRecord, advertisePacketLen,
- scanResponsePacketLen);
- if (DBG) {
- Log.d(TAG, "ScanRecord : " + Arrays.toString(scanRecord));
- }
- results.add(new ScanResult(device, ScanRecord.parseFromBytes(scanRecord), rssi,
- timestampNanos));
- }
- return results;
- }
-
- // Reverse byte array.
- private void reverse(byte[] address) {
- int len = address.length;
- for (int i = 0; i < len / 2; ++i) {
- byte b = address[i];
- address[i] = address[len - 1 - i];
- address[len - 1 - i] = b;
- }
- }
-
- // Helper method to extract bytes from byte array.
- private static byte[] extractBytes(byte[] scanRecord, int start, int length) {
- byte[] bytes = new byte[length];
- System.arraycopy(scanRecord, start, bytes, 0, length);
- return bytes;
- }
-
- @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
- void onBatchScanThresholdCrossed(int clientIf) {
- if (DBG) {
- Log.d(TAG, "onBatchScanThresholdCrossed() - clientIf=" + clientIf);
- }
- flushPendingBatchResults(clientIf, getAttributionSource());
- }
-
- AdvtFilterOnFoundOnLostInfo createOnTrackAdvFoundLostObject(int clientIf, int advPktLen,
- byte[] advPkt, int scanRspLen, byte[] scanRsp, int filtIndex, int advState,
- int advInfoPresent, String address, int addrType, int txPower, int rssiValue,
- int timeStamp) {
-
- return new AdvtFilterOnFoundOnLostInfo(clientIf, advPktLen, advPkt, scanRspLen, scanRsp,
- filtIndex, advState, advInfoPresent, address, addrType, txPower, rssiValue,
- timeStamp);
- }
-
- void onTrackAdvFoundLost(AdvtFilterOnFoundOnLostInfo trackingInfo) throws RemoteException {
- if (DBG) {
- Log.d(TAG, "onTrackAdvFoundLost() - scannerId= " + trackingInfo.getClientIf()
- + " address = " + trackingInfo.getAddress() + " adv_state = "
- + trackingInfo.getAdvState());
- }
-
- TransitionalScanHelper.ScannerMap.App app =
- mTransitionalScanHelper.getScannerMap().getById(trackingInfo.getClientIf());
- if (app == null || (app.callback == null && app.info == null)) {
- Log.e(TAG, "app or callback is null");
- return;
- }
-
- BluetoothDevice device = BluetoothAdapter.getDefaultAdapter()
- .getRemoteDevice(trackingInfo.getAddress());
- int advertiserState = trackingInfo.getAdvState();
- ScanResult result =
- new ScanResult(device, ScanRecord.parseFromBytes(trackingInfo.getResult()),
- trackingInfo.getRSSIValue(), SystemClock.elapsedRealtimeNanos());
-
- for (ScanClient client : mScanManager.getRegularScanQueue()) {
- if (client.scannerId == trackingInfo.getClientIf()) {
- ScanSettings settings = client.settings;
- if ((advertiserState == ADVT_STATE_ONFOUND) && (
- (settings.getCallbackType() & ScanSettings.CALLBACK_TYPE_FIRST_MATCH)
- != 0)) {
- if (app.callback != null) {
- app.callback.onFoundOrLost(true, result);
- } else {
- sendResultByPendingIntent(app.info, result,
- ScanSettings.CALLBACK_TYPE_FIRST_MATCH, client);
- }
- } else if ((advertiserState == ADVT_STATE_ONLOST) && (
- (settings.getCallbackType() & ScanSettings.CALLBACK_TYPE_MATCH_LOST)
- != 0)) {
- if (app.callback != null) {
- app.callback.onFoundOrLost(false, result);
- } else {
- sendResultByPendingIntent(app.info, result,
- ScanSettings.CALLBACK_TYPE_MATCH_LOST, client);
- }
- } else {
- if (DBG) {
- Log.d(TAG, "Not reporting onlost/onfound : " + advertiserState
- + " scannerId = " + client.scannerId + " callbackType "
- + settings.getCallbackType());
- }
- }
- }
- }
- }
-
- void onScanParamSetupCompleted(int status, int scannerId) throws RemoteException {
- ContextMap.App app = mTransitionalScanHelper.getScannerMap().getById(scannerId);
- if (app == null || app.callback == null) {
- Log.e(TAG, "Advertise app or callback is null");
- return;
- }
- if (DBG) {
- Log.d(TAG, "onScanParamSetupCompleted : " + status);
- }
- }
-
- // callback from ScanManager for dispatch of errors apps.
- public void onScanManagerErrorCallback(int scannerId, int errorCode) throws RemoteException {
- TransitionalScanHelper.ScannerMap.App app =
- mTransitionalScanHelper.getScannerMap().getById(scannerId);
- if (app == null || (app.callback == null && app.info == null)) {
- Log.e(TAG, "App or callback is null");
- return;
- }
- if (app.callback != null) {
- app.callback.onScanManagerErrorCallback(errorCode);
- } else {
- try {
- sendErrorByPendingIntent(app.info, errorCode);
- } catch (PendingIntent.CanceledException e) {
- Log.e(TAG, "Error sending error code via PendingIntent:" + e);
- }
- }
- }
-
void onConfigureMTU(int connId, int status, int mtu) throws RemoteException {
String address = mClientMap.addressByConnId(connId);
@@ -3203,292 +2331,6 @@ public class GattService extends ProfileService {
return deviceList;
}
- @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
- void registerScanner(IScannerCallback callback, WorkSource workSource,
- AttributionSource attributionSource) throws RemoteException {
- if (!Utils.checkScanPermissionForDataDelivery(
- this, attributionSource, "GattService registerScanner")) {
- return;
- }
-
- UUID uuid = UUID.randomUUID();
- if (DBG) {
- Log.d(TAG, "registerScanner() - UUID=" + uuid);
- }
-
- enforceImpersonatationPermissionIfNeeded(workSource);
-
- AppScanStats app = mTransitionalScanHelper.getScannerMap()
- .getAppScanStatsByUid(Binder.getCallingUid());
- if (app != null && app.isScanningTooFrequently()
- && !Utils.checkCallerHasPrivilegedPermission(this)) {
- Log.e(TAG, "App '" + app.appName + "' is scanning too frequently");
- callback.onScannerRegistered(ScanCallback.SCAN_FAILED_SCANNING_TOO_FREQUENTLY, -1);
- return;
- }
-
- mTransitionalScanHelper
- .getScannerMap().add(uuid, workSource, callback, null, this);
- mScanManager.registerScanner(uuid);
- }
-
- @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
- public void unregisterScanner(int scannerId, AttributionSource attributionSource) {
- if (!Utils.checkScanPermissionForDataDelivery(
- this, attributionSource, "GattService unregisterScanner")) {
- return;
- }
-
- if (DBG) {
- Log.d(TAG, "unregisterScanner() - scannerId=" + scannerId);
- }
- mTransitionalScanHelper.getScannerMap().remove(scannerId);
- mScanManager.unregisterScanner(scannerId);
- }
-
- private List<String> getAssociatedDevices(String callingPackage) {
- if (mCompanionManager == null) {
- return Collections.emptyList();
- }
-
- List<String> macAddresses = new ArrayList();
-
- final long identity = Binder.clearCallingIdentity();
- try {
- for (AssociationInfo info : Utils.getCdmAssociations(mCompanionManager)) {
- if (info.getPackageName().equals(callingPackage) && !info.isSelfManaged()
- && info.getDeviceMacAddress() != null) {
- macAddresses.add(info.getDeviceMacAddress().toString());
- }
- }
- } catch (SecurityException se) {
- // Not an app with associated devices
- } catch (Exception e) {
- Log.e(TAG, "Cannot check device associations for " + callingPackage, e);
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
- return macAddresses;
- }
-
- @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
- void startScan(int scannerId, ScanSettings settings, List<ScanFilter> filters,
- AttributionSource attributionSource) {
- if (DBG) {
- Log.d(TAG, "start scan with filters");
- }
-
- if (!Utils.checkScanPermissionForDataDelivery(
- this, attributionSource, "Starting GATT scan.")) {
- return;
- }
-
- enforcePrivilegedPermissionIfNeeded(settings);
- String callingPackage = attributionSource.getPackageName();
- settings = enforceReportDelayFloor(settings);
- enforcePrivilegedPermissionIfNeeded(filters);
- final ScanClient scanClient = new ScanClient(scannerId, settings, filters);
- scanClient.userHandle = Binder.getCallingUserHandle();
- mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
- scanClient.eligibleForSanitizedExposureNotification =
- callingPackage.equals(mExposureNotificationPackage);
-
- scanClient.hasDisavowedLocation =
- Utils.hasDisavowedLocationForScan(this, attributionSource, isTestModeEnabled());
-
- scanClient.isQApp = checkCallerTargetSdk(this, callingPackage, Build.VERSION_CODES.Q);
- if (!scanClient.hasDisavowedLocation) {
- if (scanClient.isQApp) {
- scanClient.hasLocationPermission = Utils.checkCallerHasFineLocation(
- this, attributionSource, scanClient.userHandle);
- } else {
- scanClient.hasLocationPermission = Utils.checkCallerHasCoarseOrFineLocation(
- this, attributionSource, scanClient.userHandle);
- }
- }
- scanClient.hasNetworkSettingsPermission =
- Utils.checkCallerHasNetworkSettingsPermission(this);
- scanClient.hasNetworkSetupWizardPermission =
- Utils.checkCallerHasNetworkSetupWizardPermission(this);
- scanClient.hasScanWithoutLocationPermission =
- Utils.checkCallerHasScanWithoutLocationPermission(this);
- scanClient.associatedDevices = getAssociatedDevices(callingPackage);
-
- AppScanStats app = mTransitionalScanHelper.getScannerMap().getAppScanStatsById(scannerId);
- ContextMap.App cbApp = mTransitionalScanHelper.getScannerMap().getById(scannerId);
- if (app != null) {
- scanClient.stats = app;
- boolean isFilteredScan = (filters != null) && !filters.isEmpty();
- boolean isCallbackScan = false;
- if (cbApp != null) {
- isCallbackScan = cbApp.callback != null;
- }
- app.recordScanStart(settings, filters, isFilteredScan, isCallbackScan, scannerId);
- }
-
- mScanManager.startScan(scanClient);
- }
-
- @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
- void registerPiAndStartScan(PendingIntent pendingIntent, ScanSettings settings,
- List<ScanFilter> filters, AttributionSource attributionSource) {
- if (DBG) {
- Log.d(TAG, "start scan with filters, for PendingIntent");
- }
-
- if (!Utils.checkScanPermissionForDataDelivery(
- this, attributionSource, "Starting GATT scan.")) {
- return;
- }
- enforcePrivilegedPermissionIfNeeded(settings);
- settings = enforceReportDelayFloor(settings);
- enforcePrivilegedPermissionIfNeeded(filters);
- UUID uuid = UUID.randomUUID();
- String callingPackage = attributionSource.getPackageName();
- int callingUid = attributionSource.getUid();
- PendingIntentInfo piInfo = new PendingIntentInfo();
- piInfo.intent = pendingIntent;
- piInfo.settings = settings;
- piInfo.filters = filters;
- piInfo.callingPackage = callingPackage;
- piInfo.callingUid = callingUid;
- if (DBG) {
- Log.d(
- TAG,
- "startScan(PI) -"
- + (" UUID=" + uuid)
- + (" Package=" + callingPackage)
- + (" UID=" + callingUid));
- }
-
- // Don't start scan if the Pi scan already in mScannerMap.
- if (mTransitionalScanHelper.getScannerMap().getByContextInfo(piInfo) != null) {
- Log.d(TAG, "Don't startScan(PI) since the same Pi scan already in mScannerMap.");
- return;
- }
-
- ContextMap.App app =
- mTransitionalScanHelper.getScannerMap().add(uuid, null, null, piInfo, this);
-
- app.mUserHandle = UserHandle.getUserHandleForUid(Binder.getCallingUid());
- mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
- app.mEligibleForSanitizedExposureNotification =
- callingPackage.equals(mExposureNotificationPackage);
-
- app.mHasDisavowedLocation =
- Utils.hasDisavowedLocationForScan(this, attributionSource, isTestModeEnabled());
-
- if (!app.mHasDisavowedLocation) {
- try {
- if (checkCallerTargetSdk(this, callingPackage, Build.VERSION_CODES.Q)) {
- app.hasLocationPermission = Utils.checkCallerHasFineLocation(
- this, attributionSource, app.mUserHandle);
- } else {
- app.hasLocationPermission = Utils.checkCallerHasCoarseOrFineLocation(
- this, attributionSource, app.mUserHandle);
- }
- } catch (SecurityException se) {
- // No need to throw here. Just mark as not granted.
- app.hasLocationPermission = false;
- }
- }
- app.mHasNetworkSettingsPermission =
- Utils.checkCallerHasNetworkSettingsPermission(this);
- app.mHasNetworkSetupWizardPermission =
- Utils.checkCallerHasNetworkSetupWizardPermission(this);
- app.mHasScanWithoutLocationPermission =
- Utils.checkCallerHasScanWithoutLocationPermission(this);
- app.mAssociatedDevices = getAssociatedDevices(callingPackage);
- mScanManager.registerScanner(uuid);
-
- // If this fails, we should stop the scan immediately.
- if (!pendingIntent.addCancelListener(Runnable::run, mScanIntentCancelListener)) {
- Log.d(TAG, "scanning PendingIntent is already cancelled, stopping scan.");
- stopScan(pendingIntent, attributionSource);
- }
- }
-
- void continuePiStartScan(int scannerId, TransitionalScanHelper.ScannerMap.App app) {
- final PendingIntentInfo piInfo = app.info;
- final ScanClient scanClient =
- new ScanClient(scannerId, piInfo.settings, piInfo.filters, piInfo.callingUid);
- scanClient.hasLocationPermission = app.hasLocationPermission;
- scanClient.userHandle = app.mUserHandle;
- scanClient.isQApp = checkCallerTargetSdk(this, app.name, Build.VERSION_CODES.Q);
- scanClient.eligibleForSanitizedExposureNotification =
- app.mEligibleForSanitizedExposureNotification;
- scanClient.hasNetworkSettingsPermission = app.mHasNetworkSettingsPermission;
- scanClient.hasNetworkSetupWizardPermission = app.mHasNetworkSetupWizardPermission;
- scanClient.hasScanWithoutLocationPermission = app.mHasScanWithoutLocationPermission;
- scanClient.associatedDevices = app.mAssociatedDevices;
- scanClient.hasDisavowedLocation = app.mHasDisavowedLocation;
-
- AppScanStats scanStats =
- mTransitionalScanHelper.getScannerMap().getAppScanStatsById(scannerId);
- if (scanStats != null) {
- scanClient.stats = scanStats;
- boolean isFilteredScan = (piInfo.filters != null) && !piInfo.filters.isEmpty();
- scanStats.recordScanStart(
- piInfo.settings, piInfo.filters, isFilteredScan, false, scannerId);
- }
-
- mScanManager.startScan(scanClient);
- }
-
- @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
- void flushPendingBatchResults(int scannerId, AttributionSource attributionSource) {
- if (!Utils.checkScanPermissionForDataDelivery(
- this, attributionSource, "GattService flushPendingBatchResults")) {
- return;
- }
- if (DBG) {
- Log.d(TAG, "flushPendingBatchResults - scannerId=" + scannerId);
- }
- mScanManager.flushBatchScanResults(new ScanClient(scannerId));
- }
-
- @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
- void stopScan(int scannerId, AttributionSource attributionSource) {
- if (!Utils.checkScanPermissionForDataDelivery(
- this, attributionSource, "GattService stopScan")) {
- return;
- }
- int scanQueueSize =
- mScanManager.getBatchScanQueue().size() + mScanManager.getRegularScanQueue().size();
- if (DBG) {
- Log.d(TAG, "stopScan() - queue size =" + scanQueueSize);
- }
-
- AppScanStats app = null;
- app = mTransitionalScanHelper.getScannerMap().getAppScanStatsById(scannerId);
- if (app != null) {
- app.recordScanStop(scannerId);
- }
-
- mScanManager.stopScan(scannerId);
- }
-
- @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
- void stopScan(PendingIntent intent, AttributionSource attributionSource) {
- if (!Utils.checkScanPermissionForDataDelivery(
- this, attributionSource, "GattService stopScan")) {
- return;
- }
- PendingIntentInfo pii = new PendingIntentInfo();
- pii.intent = intent;
- ContextMap.App app = mTransitionalScanHelper.getScannerMap().getByContextInfo(pii);
- if (VDBG) {
- Log.d(TAG, "stopScan(PendingIntent): app found = " + app);
- }
- if (app != null) {
- intent.removeCancelListener(mScanIntentCancelListener);
- final int scannerId = app.id;
- stopScan(scannerId, attributionSource);
- // Also unregister the scanner
- unregisterScanner(scannerId, attributionSource);
- }
- }
-
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
void disconnectAll(AttributionSource attributionSource) {
if (DBG) {
@@ -3515,48 +2357,6 @@ public class GattService extends ProfileService {
}
/**************************************************************************
- * PERIODIC SCANNING
- *************************************************************************/
- @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
- void registerSync(ScanResult scanResult, int skip, int timeout,
- IPeriodicAdvertisingCallback callback, AttributionSource attributionSource) {
- if (!Utils.checkScanPermissionForDataDelivery(
- this, attributionSource, "GattService registerSync")) {
- return;
- }
- mPeriodicScanManager.startSync(scanResult, skip, timeout, callback);
- }
-
- @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
- void unregisterSync(
- IPeriodicAdvertisingCallback callback, AttributionSource attributionSource) {
- if (!Utils.checkScanPermissionForDataDelivery(
- this, attributionSource, "GattService unregisterSync")) {
- return;
- }
- mPeriodicScanManager.stopSync(callback);
- }
-
- void transferSync(BluetoothDevice bda, int serviceData, int syncHandle,
- AttributionSource attributionSource) {
- if (!Utils.checkScanPermissionForDataDelivery(
- this, attributionSource, "GattService transferSync")) {
- return;
- }
- mPeriodicScanManager.transferSync(bda, serviceData, syncHandle);
- }
-
- void transferSetInfo(BluetoothDevice bda, int serviceData,
- int advHandle, IPeriodicAdvertisingCallback callback,
- AttributionSource attributionSource) {
- if (!Utils.checkScanPermissionForDataDelivery(
- this, attributionSource, "GattService transferSetInfo")) {
- return;
- }
- mPeriodicScanManager.transferSetInfo(bda, serviceData, advHandle, callback);
- }
-
- /**************************************************************************
* ADVERTISING SET
*************************************************************************/
@RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE)
@@ -3712,7 +2512,7 @@ public class GattService extends ProfileService {
if (DBG) {
Log.d(TAG, "registerClient() - UUID=" + uuid);
}
- mClientMap.add(uuid, null, callback, null, this);
+ mClientMap.add(uuid, null, callback, null, this, mTransitionalScanHelper);
mNativeInterface.gattClientRegisterApp(uuid.getLeastSignificantBits(),
uuid.getMostSignificantBits(), eatt_support);
}
@@ -3822,7 +2622,7 @@ public class GattService extends ProfileService {
return 0;
}
return (AdapterService.getAdapterService().getTotalNumOfTrackableAdvertisements()
- - mScanManager.getCurrentUsedTrackingAdvertisement());
+ - mTransitionalScanHelper.getCurrentUsedTrackingAdvertisement());
}
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
@@ -4608,7 +3408,7 @@ public class GattService extends ProfileService {
if (DBG) {
Log.d(TAG, "registerServer() - UUID=" + uuid);
}
- mServerMap.add(uuid, null, callback, null, this);
+ mServerMap.add(uuid, null, callback, null, this, mTransitionalScanHelper);
mNativeInterface.gattServerRegisterApp(uuid.getLeastSignificantBits(),
uuid.getMostSignificantBits(), eatt_support);
}
@@ -4878,87 +3678,6 @@ public class GattService extends ProfileService {
return type;
}
- private boolean needsPrivilegedPermissionForScan(ScanSettings settings) {
- // BLE scan only mode needs special permission.
- if (mAdapterService.getState() != BluetoothAdapter.STATE_ON) {
- return true;
- }
-
- // Regular scan, no special permission.
- if (settings == null) {
- return false;
- }
-
- // Ambient discovery mode, needs privileged permission.
- if (settings.getScanMode() == ScanSettings.SCAN_MODE_AMBIENT_DISCOVERY) {
- return true;
- }
-
- // Regular scan, no special permission.
- if (settings.getReportDelayMillis() == 0) {
- return false;
- }
-
- // Batch scan, truncated mode needs permission.
- return settings.getScanResultType() == ScanSettings.SCAN_RESULT_TYPE_ABBREVIATED;
- }
-
- /*
- * The {@link ScanFilter#setDeviceAddress} API overloads are @SystemApi access methods. This
- * requires that the permissions be BLUETOOTH_PRIVILEGED.
- */
- @SuppressLint("AndroidFrameworkRequiresPermission")
- private void enforcePrivilegedPermissionIfNeeded(List<ScanFilter> filters) {
- if (DBG) {
- Log.d(TAG, "enforcePrivilegedPermissionIfNeeded(" + filters + ")");
- }
- // Some 3p API cases may have null filters, need to allow
- if (filters != null) {
- for (ScanFilter filter : filters) {
- // The only case to enforce here is if there is an address
- // If there is an address, enforce if the correct combination criteria is met.
- if (filter.getDeviceAddress() != null) {
- // At this point we have an address, that means a caller used the
- // setDeviceAddress(address) public API for the ScanFilter
- // We don't want to enforce if the type is PUBLIC and the IRK is null
- // However, if we have a different type that means the caller used a new
- // @SystemApi such as setDeviceAddress(address, type) or
- // setDeviceAddress(address, type, irk) which are both @SystemApi and require
- // permissions to be enforced
- if (filter.getAddressType()
- == BluetoothDevice.ADDRESS_TYPE_PUBLIC && filter.getIrk() == null) {
- // Do not enforce
- } else {
- enforceBluetoothPrivilegedPermission(this);
- }
- }
- }
- }
- }
-
- @SuppressLint("AndroidFrameworkRequiresPermission")
- private void enforcePrivilegedPermissionIfNeeded(ScanSettings settings) {
- if (needsPrivilegedPermissionForScan(settings)) {
- enforceBluetoothPrivilegedPermission(this);
- }
- }
-
- // Enforce caller has UPDATE_DEVICE_STATS permission, which allows the caller to blame other
- // apps for Bluetooth usage. A {@link SecurityException} will be thrown if the caller app does
- // not have UPDATE_DEVICE_STATS permission.
- @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS)
- private void enforceImpersonatationPermission() {
- enforceCallingOrSelfPermission(android.Manifest.permission.UPDATE_DEVICE_STATS,
- "Need UPDATE_DEVICE_STATS permission");
- }
-
- @SuppressLint("AndroidFrameworkRequiresPermission")
- private void enforceImpersonatationPermissionIfNeeded(WorkSource workSource) {
- if (workSource != null) {
- enforceImpersonatationPermission();
- }
- }
-
private void logClientForegroundInfo(int uid, boolean isDirect) {
if (mPackageManager == null) {
return;
@@ -5015,45 +3734,6 @@ public class GattService extends ProfileService {
}
}
- /**
- * Ensures the report delay is either 0 or at least the floor value (5000ms)
- *
- * @param settings are the scan settings passed into a request to start le scanning
- * @return the passed in ScanSettings object if the report delay is 0 or above the floor value;
- * a new ScanSettings object with the report delay being the floor value if the original
- * report delay was between 0 and the floor value (exclusive of both)
- */
- @VisibleForTesting
- ScanSettings enforceReportDelayFloor(ScanSettings settings) {
- if (settings.getReportDelayMillis() == 0) {
- return settings;
- }
-
- // Need to clear identity to pass device config permission check
- final long callerToken = Binder.clearCallingIdentity();
- try {
- long floor = DeviceConfig.getLong(DeviceConfig.NAMESPACE_BLUETOOTH, "report_delay",
- DEFAULT_REPORT_DELAY_FLOOR);
-
- if (settings.getReportDelayMillis() > floor) {
- return settings;
- } else {
- return new ScanSettings.Builder()
- .setCallbackType(settings.getCallbackType())
- .setLegacy(settings.getLegacy())
- .setMatchMode(settings.getMatchMode())
- .setNumOfMatches(settings.getNumOfMatches())
- .setPhy(settings.getPhy())
- .setReportDelay(floor)
- .setScanMode(settings.getScanMode())
- .setScanResultType(settings.getScanResultType())
- .build();
- }
- } finally {
- Binder.restoreCallingIdentity(callerToken);
- }
- }
-
private void stopNextService(int serverIf, int status) throws RemoteException {
if (DBG) {
Log.d(TAG, "stopNextService() - serverIf=" + serverIf + ", status=" + status);
@@ -5122,8 +3802,6 @@ public class GattService extends ProfileService {
println(sb, " " + uuid);
}
- println(sb, "mMaxScanFilters: " + mMaxScanFilters);
-
sb.append("\nRegistered App\n");
dumpRegisterId(sb);
@@ -5143,15 +3821,6 @@ public class GattService extends ProfileService {
mHandleMap.dump(sb);
}
- public void addScanEvent(BluetoothMetricsProto.ScanEvent event) {
- synchronized (mScanEvents) {
- if (mScanEvents.size() == NUM_SCAN_EVENTS_KEPT) {
- mScanEvents.remove();
- }
- mScanEvents.add(event);
- }
- }
-
private void statsLogAppPackage(String address, int applicationUid, int sessionIndex) {
BluetoothDevice device = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(address);
BluetoothStatsLog.write(
@@ -5181,9 +3850,7 @@ public class GattService extends ProfileService {
@Override
public void dumpProto(BluetoothMetricsProto.BluetoothLog.Builder builder) {
- synchronized (mScanEvents) {
- builder.addAllScanEvent(mScanEvents);
- }
+ mTransitionalScanHelper.dumpProto(builder);
}
/**************************************************************************
diff --git a/android/app/src/com/android/bluetooth/hearingaid/HearingAidService.java b/android/app/src/com/android/bluetooth/hearingaid/HearingAidService.java
index 5937b07dd6..3d85f02dd2 100644
--- a/android/app/src/com/android/bluetooth/hearingaid/HearingAidService.java
+++ b/android/app/src/com/android/bluetooth/hearingaid/HearingAidService.java
@@ -954,15 +954,17 @@ public class HearingAidService extends ProfileService {
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
private HearingAidService getService(AttributionSource source) {
+ // Cache mService because it can change while getService is called b/327929337
+ HearingAidService service = mService;
if (mIsTesting) {
- return mService;
+ return service;
}
- if (!Utils.checkServiceAvailable(mService, TAG)
- || !Utils.checkCallerIsSystemOrActiveOrManagedUser(mService, TAG)
- || !Utils.checkConnectPermissionForDataDelivery(mService, source, TAG)) {
+ if (!Utils.checkServiceAvailable(service, TAG)
+ || !Utils.checkCallerIsSystemOrActiveOrManagedUser(service, TAG)
+ || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
return null;
}
- return mService;
+ return service;
}
BluetoothHearingAidBinder(HearingAidService svc) {
diff --git a/android/app/src/com/android/bluetooth/hfp/HeadsetService.java b/android/app/src/com/android/bluetooth/hfp/HeadsetService.java
index ed8c462109..985ac9de81 100644
--- a/android/app/src/com/android/bluetooth/hfp/HeadsetService.java
+++ b/android/app/src/com/android/bluetooth/hfp/HeadsetService.java
@@ -76,6 +76,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
+import java.util.concurrent.FutureTask;
/**
* Provides Bluetooth Headset and Handsfree profile, as a service in the Bluetooth application.
@@ -1889,7 +1890,8 @@ public class HeadsetService extends ProfileService {
mSystemInterface.getHeadsetPhoneState().setCallState(callState);
// Suspend A2DP when call about is about to become active
if (mActiveDevice != null && callState != HeadsetHalConstants.CALL_STATE_DISCONNECTED
- && !mSystemInterface.isCallIdle() && isCallIdleBefore) {
+ && !mSystemInterface.isCallIdle() && isCallIdleBefore
+ && !Flags.isScoManagedByAudio()) {
mSystemInterface.getAudioManager().setA2dpSuspended(true);
if (isAtLeastU()) {
mSystemInterface.getAudioManager().setLeAudioSuspended(true);
@@ -1899,9 +1901,25 @@ public class HeadsetService extends ProfileService {
doForEachConnectedStateMachine(
stateMachine -> stateMachine.sendMessage(HeadsetStateMachine.CALL_STATE_CHANGED,
new HeadsetCallState(numActive, numHeld, callState, number, type, name)));
+ if (Flags.isScoManagedByAudio()) {
+ if (mActiveDevice == null) {
+ Log.i(TAG, "HeadsetService's active device is null");
+ } else {
+ // wait until mActiveDevice's state machine processed CALL_STATE_CHANGED message,
+ // then Audio Framework starts the SCO connection
+ FutureTask task = new FutureTask(() -> {}, null);
+ mStateMachines.get(mActiveDevice).getHandler().post(task);
+ try {
+ task.get();
+ } catch (Exception e) {
+ Log.e(TAG,
+ "Exception when waiting for CALL_STATE_CHANGED message" + e.toString());
+ }
+ }
+ }
getStateMachinesThreadHandler().post(() -> {
if (callState == HeadsetHalConstants.CALL_STATE_IDLE
- && mSystemInterface.isCallIdle() && !isAudioOn()) {
+ && mSystemInterface.isCallIdle() && !isAudioOn() && !Flags.isScoManagedByAudio()) {
// Resume A2DP when call ended and SCO is not connected
mSystemInterface.getAudioManager().setA2dpSuspended(false);
if (isAtLeastU()) {
diff --git a/android/app/src/com/android/bluetooth/gatt/AdvtFilterOnFoundOnLostInfo.java b/android/app/src/com/android/bluetooth/le_scan/AdvtFilterOnFoundOnLostInfo.java
index c16f8269ba..5db51efb79 100644
--- a/android/app/src/com/android/bluetooth/gatt/AdvtFilterOnFoundOnLostInfo.java
+++ b/android/app/src/com/android/bluetooth/le_scan/AdvtFilterOnFoundOnLostInfo.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.bluetooth.gatt;
+package com.android.bluetooth.le_scan;
import android.annotation.Nullable;
diff --git a/android/app/src/com/android/bluetooth/le_scan/AppScanStats.java b/android/app/src/com/android/bluetooth/le_scan/AppScanStats.java
index e2ce19a0b7..1851ecef9a 100644
--- a/android/app/src/com/android/bluetooth/le_scan/AppScanStats.java
+++ b/android/app/src/com/android/bluetooth/le_scan/AppScanStats.java
@@ -19,6 +19,7 @@ package com.android.bluetooth.le_scan;
import android.bluetooth.BluetoothProtoEnums;
import android.bluetooth.le.ScanFilter;
import android.bluetooth.le.ScanSettings;
+import android.content.Context;
import android.os.BatteryStatsManager;
import android.os.Binder;
import android.os.SystemClock;
@@ -29,7 +30,6 @@ import com.android.bluetooth.BluetoothStatsLog;
import com.android.bluetooth.btservice.AdapterService;
import com.android.bluetooth.btservice.MetricsLogger;
import com.android.bluetooth.gatt.ContextMap;
-import com.android.bluetooth.gatt.GattService;
import com.android.bluetooth.util.WorkSourceUtil;
import com.android.internal.annotations.GuardedBy;
@@ -66,8 +66,8 @@ public class AppScanStats {
// ContextMap here is needed to grab Apps and Connections
ContextMap mContextMap;
- // GattService is needed to add scan event protos to be dumped later
- final GattService mGattService;
+ // TransitionalScanHelper is needed to add scan event protos to be dumped later
+ final TransitionalScanHelper mScanHelper;
// Battery stats is used to keep track of scans and result stats
BatteryStatsManager mBatteryStatsManager;
@@ -149,11 +149,16 @@ public class AppScanStats {
private long stopTime = 0;
private int results = 0;
- public AppScanStats(String name, WorkSource source, ContextMap map, GattService service) {
+ public AppScanStats(
+ String name,
+ WorkSource source,
+ ContextMap map,
+ Context context,
+ TransitionalScanHelper scanHelper) {
appName = name;
mContextMap = map;
- mGattService = service;
- mBatteryStatsManager = service.getSystemService(BatteryStatsManager.class);
+ mScanHelper = scanHelper;
+ mBatteryStatsManager = context.getSystemService(BatteryStatsManager.class);
if (source == null) {
// Bill the caller if the work source isn't passed through
@@ -263,7 +268,7 @@ public class AppScanStats {
BluetoothMetricsProto.ScanEvent.ScanTechnologyType.SCAN_TECH_TYPE_LE)
.setEventTimeMillis(System.currentTimeMillis())
.setInitiator(truncateAppName(appName)).build();
- mGattService.addScanEvent(scanEvent);
+ mScanHelper.addScanEvent(scanEvent);
if (!isScanning()) {
mScanStartTime = startTime;
@@ -308,7 +313,7 @@ public class AppScanStats {
.setInitiator(truncateAppName(appName))
.setNumberResults(scan.results)
.build();
- mGattService.addScanEvent(scanEvent);
+ mScanHelper.addScanEvent(scanEvent);
mTotalScanTime += scanDuration;
long activeDuration = scanDuration - scan.suspendDuration;
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 f39115a34e..162633f5e6 100644
--- a/android/app/src/com/android/bluetooth/le_scan/ScanManager.java
+++ b/android/app/src/com/android/bluetooth/le_scan/ScanManager.java
@@ -49,7 +49,6 @@ import com.android.bluetooth.btservice.BluetoothAdapterProxy;
import com.android.bluetooth.flags.Flags;
import com.android.bluetooth.gatt.FilterParams;
import com.android.bluetooth.gatt.GattObjectsFactory;
-import com.android.bluetooth.gatt.GattService;
import com.android.bluetooth.gatt.GattServiceConfig;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
@@ -88,9 +87,9 @@ public class ScanManager {
public static final int SCAN_MODE_SCREEN_OFF_BALANCED_WINDOW_MS = 183;
public static final int SCAN_MODE_SCREEN_OFF_BALANCED_INTERVAL_MS = 730;
- // Result type defined in bt stack. Need to be accessed by GattService.
- public static final int SCAN_RESULT_TYPE_TRUNCATED = 1;
- public static final int SCAN_RESULT_TYPE_FULL = 2;
+ // Result type defined in bt stack. Need to be accessed by TransitionalScanHelper.
+ static final int SCAN_RESULT_TYPE_TRUNCATED = 1;
+ static final int SCAN_RESULT_TYPE_FULL = 2;
static final int SCAN_RESULT_TYPE_BOTH = 3;
// Messages for handling BLE scan operations.
@@ -123,7 +122,8 @@ public class ScanManager {
@GuardedBy("mCurUsedTrackableAdvertisementsLock")
private int mCurUsedTrackableAdvertisements = 0;
- private final GattService mService;
+ private final Context mContext;
+ private final TransitionalScanHelper mScanHelper;
private final AdapterService mAdapterService;
private BroadcastReceiver mBatchAlarmReceiver;
private boolean mBatchAlarmReceiverRegistered;
@@ -164,7 +164,8 @@ public class ScanManager {
}
public ScanManager(
- GattService service,
+ Context context,
+ TransitionalScanHelper scanHelper,
AdapterService adapterService,
BluetoothAdapterProxy bluetoothAdapterProxy,
Looper looper) {
@@ -173,11 +174,12 @@ public class ScanManager {
mBatchClients = Collections.newSetFromMap(new ConcurrentHashMap<ScanClient, Boolean>());
mSuspendedScanClients =
Collections.newSetFromMap(new ConcurrentHashMap<ScanClient, Boolean>());
- mService = service;
+ mContext = context;
+ mScanHelper = scanHelper;
mAdapterService = adapterService;
mScanNative = new ScanNative();
- mDm = mService.getSystemService(DisplayManager.class);
- mActivityManager = mService.getSystemService(ActivityManager.class);
+ mDm = mContext.getSystemService(DisplayManager.class);
+ mActivityManager = mContext.getSystemService(ActivityManager.class);
mLocationManager = mAdapterService.getSystemService(LocationManager.class);
mBluetoothAdapterProxy = bluetoothAdapterProxy;
mIsConnecting = false;
@@ -204,7 +206,7 @@ public class ScanManager {
}
IntentFilter locationIntentFilter = new IntentFilter(LocationManager.MODE_CHANGED_ACTION);
locationIntentFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
- mService.registerReceiver(mLocationReceiver, locationIntentFilter);
+ mContext.registerReceiver(mLocationReceiver, locationIntentFilter);
}
public void cleanup() {
@@ -236,7 +238,7 @@ public class ScanManager {
}
try {
- mService.unregisterReceiver(mLocationReceiver);
+ mContext.unregisterReceiver(mLocationReceiver);
} catch (IllegalArgumentException e) {
Log.w(TAG, "exception when invoking unregisterReceiver(mLocationReceiver)", e);
}
@@ -523,7 +525,7 @@ public class ScanManager {
if (DBG) {
Log.d(TAG, "app died, unregister scanner - " + client.scannerId);
}
- mService.unregisterScanner(client.scannerId, mService.getAttributionSource());
+ mScanHelper.unregisterScanner(client.scannerId, mContext.getAttributionSource());
}
}
@@ -1023,10 +1025,11 @@ public class ScanManager {
mFilterIndexStack = new ArrayDeque<Integer>();
mClientFilterIndexMap = new HashMap<Integer, Deque<Integer>>();
- mAlarmManager = mService.getSystemService(AlarmManager.class);
+ mAlarmManager = mContext.getSystemService(AlarmManager.class);
Intent batchIntent = new Intent(ACTION_REFRESH_BATCHED_SCAN, null);
- mBatchScanIntervalIntent = PendingIntent.getBroadcast(mService, 0, batchIntent,
- PendingIntent.FLAG_IMMUTABLE);
+ mBatchScanIntervalIntent =
+ PendingIntent.getBroadcast(
+ mContext, 0, batchIntent, PendingIntent.FLAG_IMMUTABLE);
IntentFilter filter = new IntentFilter();
filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
filter.addAction(ACTION_REFRESH_BATCHED_SCAN);
@@ -1047,7 +1050,7 @@ public class ScanManager {
}
}
};
- mService.registerReceiver(mBatchAlarmReceiver, filter);
+ mContext.registerReceiver(mBatchAlarmReceiver, filter);
mBatchAlarmReceiverRegistered = true;
}
@@ -1292,7 +1295,7 @@ public class ScanManager {
// infrequently anyway. To avoid redefining paramete sets, map to the low duty cycle
// parameter set as follows.
private int getBatchScanWindowMillis(int scanMode) {
- ContentResolver resolver = mService.getContentResolver();
+ ContentResolver resolver = mContext.getContentResolver();
switch (scanMode) {
case ScanSettings.SCAN_MODE_LOW_LATENCY:
return Settings.Global.getInt(
@@ -1310,7 +1313,7 @@ public class ScanManager {
}
private int getBatchScanIntervalMillis(int scanMode) {
- ContentResolver resolver = mService.getContentResolver();
+ ContentResolver resolver = mContext.getContentResolver();
switch (scanMode) {
case ScanSettings.SCAN_MODE_LOW_LATENCY:
return Settings.Global.getInt(
@@ -1357,8 +1360,8 @@ public class ScanManager {
Log.e(TAG, "Error freeing for onfound/onlost filter resources "
+ entriesToFree);
try {
- mService.onScanManagerErrorCallback(client.scannerId,
- ScanCallback.SCAN_FAILED_INTERNAL_ERROR);
+ mScanHelper.onScanManagerErrorCallback(
+ client.scannerId, ScanCallback.SCAN_FAILED_INTERNAL_ERROR);
} catch (RemoteException e) {
Log.e(TAG, "failed on onScanManagerCallback at freeing", e);
}
@@ -1480,7 +1483,7 @@ public class ScanManager {
mAlarmManager.cancel(mBatchScanIntervalIntent);
// Protect against multiple calls of cleanup.
if (mBatchAlarmReceiverRegistered) {
- mService.unregisterReceiver(mBatchAlarmReceiver);
+ mContext.unregisterReceiver(mBatchAlarmReceiver);
}
mBatchAlarmReceiverRegistered = false;
}
@@ -1547,8 +1550,8 @@ public class ScanManager {
+ trackEntries);
client.stats.recordTrackingHwFilterNotAvailableCountMetrics();
try {
- mService.onScanManagerErrorCallback(scannerId,
- ScanCallback.SCAN_FAILED_INTERNAL_ERROR);
+ mScanHelper.onScanManagerErrorCallback(
+ scannerId, ScanCallback.SCAN_FAILED_INTERNAL_ERROR);
} catch (RemoteException e) {
Log.e(TAG, "failed on onScanManagerCallback", e);
}
@@ -1706,7 +1709,7 @@ public class ScanManager {
}
private int getScanWindowMillis(ScanSettings settings) {
- ContentResolver resolver = mService.getContentResolver();
+ ContentResolver resolver = mContext.getContentResolver();
if (settings == null) {
return Settings.Global.getInt(
resolver,
@@ -1744,7 +1747,7 @@ public class ScanManager {
}
private int getScanIntervalMillis(ScanSettings settings) {
- ContentResolver resolver = mService.getContentResolver();
+ ContentResolver resolver = mContext.getContentResolver();
if (settings == null) {
return Settings.Global.getInt(
resolver,
@@ -1919,8 +1922,7 @@ public class ScanManager {
new ActivityManager.OnUidImportanceListener() {
@Override
public void onUidImportance(final int uid, final int importance) {
- if (mService.mTransitionalScanHelper.getScannerMap().getAppScanStatsByUid(uid)
- != null) {
+ if (mScanHelper.getScannerMap().getAppScanStatsByUid(uid) != null) {
Message message = new Message();
message.what = MSG_IMPORTANCE_CHANGE;
message.obj = new UidImportance(uid, importance);
diff --git a/android/app/src/com/android/bluetooth/le_scan/TransitionalScanHelper.java b/android/app/src/com/android/bluetooth/le_scan/TransitionalScanHelper.java
index 913cc40478..35cceca4b9 100644
--- a/android/app/src/com/android/bluetooth/le_scan/TransitionalScanHelper.java
+++ b/android/app/src/com/android/bluetooth/le_scan/TransitionalScanHelper.java
@@ -16,12 +16,63 @@
package com.android.bluetooth.le_scan;
+import static com.android.bluetooth.Utils.checkCallerTargetSdk;
+import static com.android.bluetooth.Utils.enforceBluetoothPrivilegedPermission;
+
+import android.annotation.RequiresPermission;
+import android.annotation.SuppressLint;
+import android.app.AppOpsManager;
+import android.app.PendingIntent;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.le.BluetoothLeScanner;
+import android.bluetooth.le.IPeriodicAdvertisingCallback;
import android.bluetooth.le.IScannerCallback;
+import android.bluetooth.le.ScanCallback;
+import android.bluetooth.le.ScanFilter;
+import android.bluetooth.le.ScanRecord;
+import android.bluetooth.le.ScanResult;
+import android.bluetooth.le.ScanSettings;
+import android.companion.AssociationInfo;
+import android.companion.CompanionDeviceManager;
+import android.content.AttributionSource;
+import android.content.Context;
+import android.content.Intent;
+import android.net.MacAddress;
+import android.os.Binder;
+import android.os.Build;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.os.UserHandle;
+import android.os.WorkSource;
+import android.provider.DeviceConfig;
+import android.util.Log;
+import com.android.bluetooth.BluetoothMetricsProto;
+import com.android.bluetooth.R;
+import com.android.bluetooth.Utils;
+import com.android.bluetooth.btservice.AdapterService;
+import com.android.bluetooth.btservice.BluetoothAdapterProxy;
+import com.android.bluetooth.flags.Flags;
import com.android.bluetooth.gatt.ContextMap;
-import com.android.bluetooth.gatt.GattService;
+import com.android.bluetooth.gatt.GattObjectsFactory;
+import com.android.bluetooth.gatt.GattServiceConfig;
+import com.android.bluetooth.util.NumberUtils;
import com.android.internal.annotations.VisibleForTesting;
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Predicate;
+
/**
* A helper class which contains all scan related functions extracted from {@link
* com.android.bluetooth.gatt.GattService}. The purpose of this class is to preserve scan
@@ -31,12 +82,102 @@ import com.android.internal.annotations.VisibleForTesting;
* @hide
*/
public class TransitionalScanHelper {
+ private static final boolean DBG = GattServiceConfig.DBG;
+ private static final boolean VDBG = GattServiceConfig.VDBG;
+ private static final String TAG = GattServiceConfig.TAG_PREFIX + "ScanHelper";
+
+ // Batch scan related constants.
+ private static final int TRUNCATED_RESULT_SIZE = 11;
+ private static final int TIME_STAMP_LENGTH = 2;
+
+ static final int SCAN_FILTER_ENABLED = 1;
+ static final int SCAN_FILTER_MODIFIED = 2;
+
+ /** The default floor value for LE batch scan report delays greater than 0 */
+ @VisibleForTesting static final long DEFAULT_REPORT_DELAY_FLOOR = 5000;
+
+ private static final int NUM_SCAN_EVENTS_KEPT = 20;
+
+ // onFoundLost related constants
+ private static final int ADVT_STATE_ONFOUND = 0;
+ private static final int ADVT_STATE_ONLOST = 1;
+
+ private static final int ET_LEGACY_MASK = 0x10;
/** List of our registered scanners. */
- public static class ScannerMap
- extends ContextMap<IScannerCallback, GattService.PendingIntentInfo> {}
+ // TODO(b/327849650): Remove as this class adds no value. Using generics this ways is considered
+ // an anti-pattern.
+ public static class ScannerMap extends ContextMap<IScannerCallback, PendingIntentInfo> {}
+
+ /** Keep the arguments passed in for the PendingIntent. */
+ public static class PendingIntentInfo {
+ public PendingIntent intent;
+ public ScanSettings settings;
+ public List<ScanFilter> filters;
+ public String callingPackage;
+ public int callingUid;
+
+ @Override
+ public boolean equals(Object other) {
+ if (!(other instanceof PendingIntentInfo)) {
+ return false;
+ }
+ return intent.equals(((PendingIntentInfo) other).intent);
+ }
+
+ @Override
+ public int hashCode() {
+ return intent == null ? 0 : intent.hashCode();
+ }
+ }
+
+ public interface TestModeAccessor {
+ /** Indicates if bluetooth test mode is enabled. */
+ boolean isTestModeEnabled();
+ }
+
+ private enum MatchOrigin {
+ PSEUDO_ADDRESS,
+ ORIGINAL_ADDRESS
+ }
+
+ private static class MatchResult {
+ private final boolean mMatches;
+ private final MatchOrigin mOrigin;
+
+ private MatchResult(boolean matches, MatchOrigin origin) {
+ this.mMatches = matches;
+ this.mOrigin = origin;
+ }
+
+ public boolean getMatches() {
+ return mMatches;
+ }
+
+ public MatchOrigin getMatchOrigin() {
+ return mOrigin;
+ }
+ }
+
+ private final PendingIntent.CancelListener mScanIntentCancelListener =
+ new PendingIntent.CancelListener() {
+ public void onCanceled(PendingIntent intent) {
+ Log.d(TAG, "scanning PendingIntent canceled");
+ stopScan(intent, mContext.getAttributionSource());
+ }
+ };
+
+ private Context mContext;
+ private TestModeAccessor mTestModeAccessor;
+
+ private AppOpsManager mAppOps;
+ private CompanionDeviceManager mCompanionManager;
+ private PeriodicScanManager mPeriodicScanManager;
+ private ScanManager mScanManager;
+ private AdapterService mAdapterService;
private ScannerMap mScannerMap = new ScannerMap();
+ private String mExposureNotificationPackage;
public ScannerMap getScannerMap() {
return mScannerMap;
@@ -46,4 +187,1475 @@ public class TransitionalScanHelper {
public void setScannerMap(ScannerMap scannerMap) {
mScannerMap = scannerMap;
}
+
+ /** Internal list of scan events to use with the proto */
+ private final ArrayDeque<BluetoothMetricsProto.ScanEvent> mScanEvents =
+ new ArrayDeque<>(NUM_SCAN_EVENTS_KEPT);
+
+ /** */
+ private final Predicate<ScanResult> mLocationDenylistPredicate =
+ (scanResult) -> {
+ final MacAddress parsedAddress =
+ MacAddress.fromString(scanResult.getDevice().getAddress());
+ if (mAdapterService.getLocationDenylistMac().test(parsedAddress.toByteArray())) {
+ Log.v(TAG, "Skipping device matching denylist: " + scanResult.getDevice());
+ return true;
+ }
+ final ScanRecord scanRecord = scanResult.getScanRecord();
+ if (scanRecord.matchesAnyField(
+ mAdapterService.getLocationDenylistAdvertisingData())) {
+ Log.v(TAG, "Skipping data matching denylist: " + scanRecord);
+ return true;
+ }
+ return false;
+ };
+
+ public TransitionalScanHelper(Context context, TestModeAccessor testModeAccessor) {
+ mContext = context;
+ mTestModeAccessor = testModeAccessor;
+ }
+
+ /**
+ * Starts the LE scanning component.
+ *
+ * @param looper for scan operations
+ */
+ public void start(Looper looper) {
+ mExposureNotificationPackage = mContext.getString(R.string.exposure_notification_package);
+ mAppOps = mContext.getSystemService(AppOpsManager.class);
+ mCompanionManager = mContext.getSystemService(CompanionDeviceManager.class);
+ mAdapterService = AdapterService.getAdapterService();
+ mScanManager =
+ GattObjectsFactory.getInstance()
+ .createScanManager(
+ mContext,
+ this,
+ mAdapterService,
+ BluetoothAdapterProxy.getInstance(),
+ looper);
+
+ mPeriodicScanManager =
+ GattObjectsFactory.getInstance().createPeriodicScanManager(mAdapterService);
+ }
+
+ /** Stops the scanning component. */
+ public void stop() {
+ mScannerMap.clear();
+ }
+
+ /** Cleans up the scanning component. */
+ public void cleanup() {
+ if (mScanManager != null) {
+ mScanManager.cleanup();
+ }
+ if (mPeriodicScanManager != null) {
+ mPeriodicScanManager.cleanup();
+ }
+ }
+
+ /** Notifies scan manager of bluetooth profile connection state changes */
+ public void notifyProfileConnectionStateChange(int profile, int fromState, int toState) {
+ if (mScanManager == null) {
+ Log.w(TAG, "scan manager is null");
+ return;
+ }
+ mScanManager.handleBluetoothProfileConnectionStateChanged(profile, fromState, toState);
+ }
+
+ public int getCurrentUsedTrackingAdvertisement() {
+ return mScanManager.getCurrentUsedTrackingAdvertisement();
+ }
+
+ /**************************************************************************
+ * Callback functions - CLIENT
+ *************************************************************************/
+
+ // EN format defined here:
+ // https://blog.google/documents/70/Exposure_Notification_-_Bluetooth_Specification_v1.2.2.pdf
+ private static final byte[] EXPOSURE_NOTIFICATION_FLAGS_PREAMBLE =
+ new byte[] {
+ // size 2, flag field, flags byte (value is not important)
+ (byte) 0x02, (byte) 0x01
+ };
+
+ private static final int EXPOSURE_NOTIFICATION_FLAGS_LENGTH = 0x2 + 1;
+ private static final byte[] EXPOSURE_NOTIFICATION_PAYLOAD_PREAMBLE =
+ new byte[] {
+ // size 3, complete 16 bit UUID, EN UUID
+ (byte) 0x03, (byte) 0x03, (byte) 0x6F, (byte) 0xFD,
+ // size 23, data for 16 bit UUID, EN UUID
+ (byte) 0x17, (byte) 0x16, (byte) 0x6F, (byte) 0xFD,
+ // ...payload
+ };
+ private static final int EXPOSURE_NOTIFICATION_PAYLOAD_LENGTH = 0x03 + 0x17 + 2;
+
+ private static boolean arrayStartsWith(byte[] array, byte[] prefix) {
+ if (array.length < prefix.length) {
+ return false;
+ }
+ for (int i = 0; i < prefix.length; i++) {
+ if (prefix[i] != array[i]) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private ScanResult getSanitizedExposureNotification(ScanResult result) {
+ ScanRecord record = result.getScanRecord();
+ // Remove the flags part of the payload, if present
+ if (record.getBytes().length > EXPOSURE_NOTIFICATION_FLAGS_LENGTH
+ && arrayStartsWith(record.getBytes(), EXPOSURE_NOTIFICATION_FLAGS_PREAMBLE)) {
+ record =
+ ScanRecord.parseFromBytes(
+ Arrays.copyOfRange(
+ record.getBytes(),
+ EXPOSURE_NOTIFICATION_FLAGS_LENGTH,
+ record.getBytes().length));
+ }
+
+ if (record.getBytes().length != EXPOSURE_NOTIFICATION_PAYLOAD_LENGTH) {
+ return null;
+ }
+ if (!arrayStartsWith(record.getBytes(), EXPOSURE_NOTIFICATION_PAYLOAD_PREAMBLE)) {
+ return null;
+ }
+
+ return new ScanResult(null, 0, 0, 0, 0, 0, result.getRssi(), 0, record, 0);
+ }
+
+ /** Callback method for a scan result. */
+ public void onScanResult(
+ int eventType,
+ int addressType,
+ String address,
+ int primaryPhy,
+ int secondaryPhy,
+ int advertisingSid,
+ int txPower,
+ int rssi,
+ int periodicAdvInt,
+ byte[] advData,
+ String originalAddress) {
+ // When in testing mode, ignore all real-world events
+ if (mTestModeAccessor.isTestModeEnabled()) return;
+
+ AppScanStats.recordScanRadioResultCount();
+ onScanResultInternal(
+ eventType,
+ addressType,
+ address,
+ primaryPhy,
+ secondaryPhy,
+ advertisingSid,
+ txPower,
+ rssi,
+ periodicAdvInt,
+ advData,
+ originalAddress);
+ }
+
+ // TODO(b/327849650): Refactor to reduce the visibility of this method.
+ public void onScanResultInternal(
+ int eventType,
+ int addressType,
+ String address,
+ int primaryPhy,
+ int secondaryPhy,
+ int advertisingSid,
+ int txPower,
+ int rssi,
+ int periodicAdvInt,
+ byte[] advData,
+ String originalAddress) {
+ if (VDBG) {
+ Log.d(
+ TAG,
+ "onScanResult() - eventType=0x"
+ + Integer.toHexString(eventType)
+ + ", addressType="
+ + addressType
+ + ", address="
+ + address
+ + ", primaryPhy="
+ + primaryPhy
+ + ", secondaryPhy="
+ + secondaryPhy
+ + ", advertisingSid=0x"
+ + Integer.toHexString(advertisingSid)
+ + ", txPower="
+ + txPower
+ + ", rssi="
+ + rssi
+ + ", periodicAdvInt=0x"
+ + Integer.toHexString(periodicAdvInt)
+ + ", originalAddress="
+ + originalAddress);
+ }
+
+ String identityAddress = mAdapterService.getIdentityAddress(address);
+ if (!address.equals(identityAddress)) {
+ if (VDBG) {
+ Log.d(
+ TAG,
+ "found identityAddress of "
+ + address
+ + ", replace originalAddress as "
+ + identityAddress);
+ }
+ originalAddress = identityAddress;
+ }
+
+ byte[] legacyAdvData = Arrays.copyOfRange(advData, 0, 62);
+
+ for (ScanClient client : mScanManager.getRegularScanQueue()) {
+ ScannerMap.App app = mScannerMap.getById(client.scannerId);
+ if (app == null) {
+ if (VDBG) {
+ Log.d(TAG, "App is null; skip.");
+ }
+ continue;
+ }
+
+ BluetoothDevice device =
+ BluetoothAdapter.getDefaultAdapter().getRemoteLeDevice(address, addressType);
+
+ ScanSettings settings = client.settings;
+ byte[] scanRecordData;
+ // This is for compatibility with applications that assume fixed size scan data.
+ if (settings.getLegacy()) {
+ if ((eventType & ET_LEGACY_MASK) == 0) {
+ // If this is legacy scan, but nonlegacy result - skip.
+ if (VDBG) {
+ Log.d(TAG, "Legacy scan, non legacy result; skip.");
+ }
+ continue;
+ } else {
+ // Some apps are used to fixed-size advertise data.
+ scanRecordData = legacyAdvData;
+ }
+ } else {
+ scanRecordData = advData;
+ }
+
+ ScanRecord scanRecord = ScanRecord.parseFromBytes(scanRecordData);
+ ScanResult result =
+ new ScanResult(
+ device,
+ eventType,
+ primaryPhy,
+ secondaryPhy,
+ advertisingSid,
+ txPower,
+ rssi,
+ periodicAdvInt,
+ scanRecord,
+ SystemClock.elapsedRealtimeNanos());
+
+ if (client.hasDisavowedLocation) {
+ if (mLocationDenylistPredicate.test(result)) {
+ Log.i(TAG, "Skipping client for location deny list");
+ continue;
+ }
+ }
+
+ boolean hasPermission = hasScanResultPermission(client);
+ if (!hasPermission) {
+ for (String associatedDevice : client.associatedDevices) {
+ if (associatedDevice.equalsIgnoreCase(address)) {
+ hasPermission = true;
+ break;
+ }
+ }
+ }
+ if (!hasPermission && client.eligibleForSanitizedExposureNotification) {
+ ScanResult sanitized = getSanitizedExposureNotification(result);
+ if (sanitized != null) {
+ hasPermission = true;
+ result = sanitized;
+ }
+ }
+ MatchResult matchResult = matchesFilters(client, result, originalAddress);
+ if (!hasPermission || !matchResult.getMatches()) {
+ if (VDBG) {
+ Log.d(
+ TAG,
+ "Skipping client: permission="
+ + hasPermission
+ + " matches="
+ + matchResult.getMatches());
+ }
+ continue;
+ }
+
+ int callbackType = settings.getCallbackType();
+ if (!(callbackType == ScanSettings.CALLBACK_TYPE_ALL_MATCHES
+ || callbackType == ScanSettings.CALLBACK_TYPE_ALL_MATCHES_AUTO_BATCH)) {
+ if (VDBG) {
+ Log.d(TAG, "Skipping client: CALLBACK_TYPE_ALL_MATCHES");
+ }
+ continue;
+ }
+
+ try {
+ app.appScanStats.addResult(client.scannerId);
+ if (app.callback != null) {
+ app.callback.onScanResult(result);
+ } else {
+ // Send the PendingIntent
+ ArrayList<ScanResult> results = new ArrayList<>();
+ results.add(result);
+ sendResultsByPendingIntent(
+ app.info, results, ScanSettings.CALLBACK_TYPE_ALL_MATCHES);
+ }
+ } catch (RemoteException | PendingIntent.CanceledException e) {
+ Log.e(TAG, "Exception: " + e);
+ if (Flags.leScanFixRemoteException()) {
+ handleDeadScanClient(client);
+ } else {
+ mScannerMap.remove(client.scannerId);
+ mScanManager.stopScan(client.scannerId);
+ }
+ }
+ }
+ }
+
+ private void sendResultByPendingIntent(
+ PendingIntentInfo pii, ScanResult result, int callbackType, ScanClient client) {
+ ArrayList<ScanResult> results = new ArrayList<>();
+ results.add(result);
+ try {
+ sendResultsByPendingIntent(pii, results, callbackType);
+ } catch (PendingIntent.CanceledException e) {
+ final long token = Binder.clearCallingIdentity();
+ try {
+ stopScan(client.scannerId, mContext.getAttributionSource());
+ unregisterScanner(client.scannerId, mContext.getAttributionSource());
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+ }
+
+ private void sendResultsByPendingIntent(
+ PendingIntentInfo pii, ArrayList<ScanResult> results, int callbackType)
+ throws PendingIntent.CanceledException {
+ Intent extrasIntent = new Intent();
+ extrasIntent.putParcelableArrayListExtra(
+ BluetoothLeScanner.EXTRA_LIST_SCAN_RESULT, results);
+ extrasIntent.putExtra(BluetoothLeScanner.EXTRA_CALLBACK_TYPE, callbackType);
+ pii.intent.send(mContext, 0, extrasIntent);
+ }
+
+ private void sendErrorByPendingIntent(PendingIntentInfo pii, int errorCode)
+ throws PendingIntent.CanceledException {
+ Intent extrasIntent = new Intent();
+ extrasIntent.putExtra(BluetoothLeScanner.EXTRA_ERROR_CODE, errorCode);
+ pii.intent.send(mContext, 0, extrasIntent);
+ }
+
+ /** Callback method for scanner registration. */
+ public void onScannerRegistered(int status, int scannerId, long uuidLsb, long uuidMsb)
+ throws RemoteException {
+ UUID uuid = new UUID(uuidMsb, uuidLsb);
+ if (DBG) {
+ Log.d(
+ TAG,
+ "onScannerRegistered() - UUID="
+ + uuid
+ + ", scannerId="
+ + scannerId
+ + ", status="
+ + status);
+ }
+
+ // First check the callback map
+ ScannerMap.App cbApp = mScannerMap.getByUuid(uuid);
+ if (cbApp != null) {
+ if (status == 0) {
+ cbApp.id = scannerId;
+ // If app is callback based, setup a death recipient. App will initiate the start.
+ // Otherwise, if PendingIntent based, start the scan directly.
+ if (cbApp.callback != null) {
+ cbApp.linkToDeath(new ScannerDeathRecipient(scannerId, cbApp.name));
+ } else {
+ continuePiStartScan(scannerId, cbApp);
+ }
+ } else {
+ mScannerMap.remove(scannerId);
+ }
+ if (cbApp.callback != null) {
+ cbApp.callback.onScannerRegistered(status, scannerId);
+ }
+ }
+ }
+
+ /** Determines if the given scan client has the appropriate permissions to receive callbacks. */
+ private boolean hasScanResultPermission(final ScanClient client) {
+ if (client.hasNetworkSettingsPermission
+ || client.hasNetworkSetupWizardPermission
+ || client.hasScanWithoutLocationPermission) {
+ return true;
+ }
+ if (client.hasDisavowedLocation) {
+ return true;
+ }
+ return client.hasLocationPermission
+ && !Utils.blockedByLocationOff(mContext, client.userHandle);
+ }
+
+ // Check if a scan record matches a specific filters.
+ private MatchResult matchesFilters(ScanClient client, ScanResult scanResult) {
+ return matchesFilters(client, scanResult, null);
+ }
+
+ // Check if a scan record matches a specific filters or original address
+ private MatchResult matchesFilters(
+ ScanClient client, ScanResult scanResult, String originalAddress) {
+ if (client.filters == null || client.filters.isEmpty()) {
+ // TODO: Do we really wanna return true here?
+ return new MatchResult(true, MatchOrigin.PSEUDO_ADDRESS);
+ }
+ for (ScanFilter filter : client.filters) {
+ // Need to check the filter matches, and the original address without changing the API
+ if (filter.matches(scanResult)) {
+ return new MatchResult(true, MatchOrigin.PSEUDO_ADDRESS);
+ }
+ if (originalAddress != null
+ && originalAddress.equalsIgnoreCase(filter.getDeviceAddress())) {
+ return new MatchResult(true, MatchOrigin.ORIGINAL_ADDRESS);
+ }
+ }
+ return new MatchResult(false, MatchOrigin.PSEUDO_ADDRESS);
+ }
+
+ private void handleDeadScanClient(ScanClient client) {
+ if (client.appDied) {
+ Log.w(TAG, "Already dead client " + client.scannerId);
+ return;
+ }
+ client.appDied = true;
+ stopScan(client.scannerId, mContext.getAttributionSource());
+ }
+
+ /** Callback method for scan filter enablement/disablement. */
+ public void onScanFilterEnableDisabled(int action, int status, int clientIf) {
+ if (DBG) {
+ Log.d(
+ TAG,
+ "onScanFilterEnableDisabled() - clientIf="
+ + clientIf
+ + ", status="
+ + status
+ + ", action="
+ + action);
+ }
+ mScanManager.callbackDone(clientIf, status);
+ }
+
+ /** Callback method for configuration of scan filter params. */
+ public void onScanFilterParamsConfigured(
+ int action, int status, int clientIf, int availableSpace) {
+ if (DBG) {
+ Log.d(
+ TAG,
+ "onScanFilterParamsConfigured() - clientIf="
+ + clientIf
+ + ", status="
+ + status
+ + ", action="
+ + action
+ + ", availableSpace="
+ + availableSpace);
+ }
+ mScanManager.callbackDone(clientIf, status);
+ }
+
+ /** Callback method for configuration of scan filter. */
+ public void onScanFilterConfig(
+ int action, int status, int clientIf, int filterType, int availableSpace) {
+ if (DBG) {
+ Log.d(
+ TAG,
+ "onScanFilterConfig() - clientIf="
+ + clientIf
+ + ", action = "
+ + action
+ + " status = "
+ + status
+ + ", filterType="
+ + filterType
+ + ", availableSpace="
+ + availableSpace);
+ }
+
+ mScanManager.callbackDone(clientIf, status);
+ }
+
+ /** Callback method for configuration of batch scan storage. */
+ public void onBatchScanStorageConfigured(int status, int clientIf) {
+ if (DBG) {
+ Log.d(
+ TAG,
+ "onBatchScanStorageConfigured() - clientIf=" + clientIf + ", status=" + status);
+ }
+ mScanManager.callbackDone(clientIf, status);
+ }
+
+ /** Callback method for start/stop of batch scan. */
+ // TODO: split into two different callbacks : onBatchScanStarted and onBatchScanStopped.
+ public void onBatchScanStartStopped(int startStopAction, int status, int clientIf) {
+ if (DBG) {
+ Log.d(
+ TAG,
+ "onBatchScanStartStopped() - clientIf="
+ + clientIf
+ + ", status="
+ + status
+ + ", startStopAction="
+ + startStopAction);
+ }
+ mScanManager.callbackDone(clientIf, status);
+ }
+
+ ScanClient findBatchScanClientById(int scannerId) {
+ for (ScanClient client : mScanManager.getBatchScanQueue()) {
+ if (client.scannerId == scannerId) {
+ return client;
+ }
+ }
+ return null;
+ }
+
+ /** Callback method for batch scan reports */
+ public void onBatchScanReports(
+ int status, int scannerId, int reportType, int numRecords, byte[] recordData)
+ throws RemoteException {
+ // When in testing mode, ignore all real-world events
+ if (mTestModeAccessor.isTestModeEnabled()) return;
+
+ AppScanStats.recordBatchScanRadioResultCount(numRecords);
+ onBatchScanReportsInternal(status, scannerId, reportType, numRecords, recordData);
+ }
+
+ @VisibleForTesting
+ void onBatchScanReportsInternal(
+ int status, int scannerId, int reportType, int numRecords, byte[] recordData)
+ throws RemoteException {
+ if (DBG) {
+ Log.d(
+ TAG,
+ "onBatchScanReports() - scannerId="
+ + scannerId
+ + ", status="
+ + status
+ + ", reportType="
+ + reportType
+ + ", numRecords="
+ + numRecords);
+ }
+
+ Set<ScanResult> results = parseBatchScanResults(numRecords, reportType, recordData);
+ if (reportType == ScanManager.SCAN_RESULT_TYPE_TRUNCATED) {
+ // We only support single client for truncated mode.
+ ScannerMap.App app = mScannerMap.getById(scannerId);
+ if (app == null) {
+ return;
+ }
+
+ ScanClient client = findBatchScanClientById(scannerId);
+ if (client == null) {
+ return;
+ }
+
+ ArrayList<ScanResult> permittedResults;
+ if (hasScanResultPermission(client)) {
+ permittedResults = new ArrayList<ScanResult>(results);
+ } else {
+ permittedResults = new ArrayList<ScanResult>();
+ for (ScanResult scanResult : results) {
+ for (String associatedDevice : client.associatedDevices) {
+ if (associatedDevice.equalsIgnoreCase(
+ scanResult.getDevice().getAddress())) {
+ permittedResults.add(scanResult);
+ }
+ }
+ }
+ if (permittedResults.isEmpty()) {
+ return;
+ }
+ }
+
+ if (client.hasDisavowedLocation) {
+ permittedResults.removeIf(mLocationDenylistPredicate);
+ }
+
+ if (app.callback != null) {
+ app.callback.onBatchScanResults(permittedResults);
+ } else {
+ // PendingIntent based
+ try {
+ sendResultsByPendingIntent(
+ app.info, permittedResults, ScanSettings.CALLBACK_TYPE_ALL_MATCHES);
+ } catch (PendingIntent.CanceledException e) {
+ }
+ }
+ } else {
+ for (ScanClient client : mScanManager.getFullBatchScanQueue()) {
+ // Deliver results for each client.
+ deliverBatchScan(client, results);
+ }
+ }
+ mScanManager.callbackDone(scannerId, status);
+ }
+
+ private void sendBatchScanResults(
+ ScannerMap.App app, ScanClient client, ArrayList<ScanResult> results) {
+ try {
+ if (app.callback != null) {
+ if (mScanManager.isAutoBatchScanClientEnabled(client)) {
+ if (DBG) {
+ Log.d(TAG, "sendBatchScanResults() to onScanResult()" + client);
+ }
+ for (ScanResult result : results) {
+ app.appScanStats.addResult(client.scannerId);
+ app.callback.onScanResult(result);
+ }
+ } else {
+ if (DBG) {
+ Log.d(TAG, "sendBatchScanResults() to onBatchScanResults()" + client);
+ }
+ app.callback.onBatchScanResults(results);
+ }
+ } else {
+ sendResultsByPendingIntent(
+ app.info, results, ScanSettings.CALLBACK_TYPE_ALL_MATCHES);
+ }
+ } catch (RemoteException | PendingIntent.CanceledException e) {
+ Log.e(TAG, "Exception: " + e);
+ if (Flags.leScanFixRemoteException()) {
+ handleDeadScanClient(client);
+ } else {
+ mScannerMap.remove(client.scannerId);
+ mScanManager.stopScan(client.scannerId);
+ }
+ }
+ }
+
+ // Check and deliver scan results for different scan clients.
+ private void deliverBatchScan(ScanClient client, Set<ScanResult> allResults)
+ throws RemoteException {
+ ContextMap.App app = mScannerMap.getById(client.scannerId);
+ if (app == null) {
+ return;
+ }
+
+ ArrayList<ScanResult> permittedResults;
+ if (hasScanResultPermission(client)) {
+ permittedResults = new ArrayList<ScanResult>(allResults);
+ } else {
+ permittedResults = new ArrayList<ScanResult>();
+ for (ScanResult scanResult : allResults) {
+ for (String associatedDevice : client.associatedDevices) {
+ if (associatedDevice.equalsIgnoreCase(scanResult.getDevice().getAddress())) {
+ permittedResults.add(scanResult);
+ }
+ }
+ }
+ if (permittedResults.isEmpty()) {
+ return;
+ }
+ }
+
+ if (client.filters == null || client.filters.isEmpty()) {
+ sendBatchScanResults(app, client, permittedResults);
+ // TODO: Question to reviewer: Shouldn't there be a return here?
+ }
+ // Reconstruct the scan results.
+ ArrayList<ScanResult> results = new ArrayList<ScanResult>();
+ for (ScanResult scanResult : permittedResults) {
+ if (matchesFilters(client, scanResult).getMatches()) {
+ results.add(scanResult);
+ }
+ }
+ sendBatchScanResults(app, client, results);
+ }
+
+ private Set<ScanResult> parseBatchScanResults(
+ int numRecords, int reportType, byte[] batchRecord) {
+ if (numRecords == 0) {
+ return Collections.emptySet();
+ }
+ if (DBG) {
+ Log.d(TAG, "current time is " + SystemClock.elapsedRealtimeNanos());
+ }
+ if (reportType == ScanManager.SCAN_RESULT_TYPE_TRUNCATED) {
+ return parseTruncatedResults(numRecords, batchRecord);
+ } else {
+ return parseFullResults(numRecords, batchRecord);
+ }
+ }
+
+ private Set<ScanResult> parseTruncatedResults(int numRecords, byte[] batchRecord) {
+ if (DBG) {
+ Log.d(TAG, "batch record " + Arrays.toString(batchRecord));
+ }
+ Set<ScanResult> results = new HashSet<ScanResult>(numRecords);
+ long now = SystemClock.elapsedRealtimeNanos();
+ for (int i = 0; i < numRecords; ++i) {
+ byte[] record =
+ extractBytes(batchRecord, i * TRUNCATED_RESULT_SIZE, TRUNCATED_RESULT_SIZE);
+ byte[] address = extractBytes(record, 0, 6);
+ reverse(address);
+ BluetoothDevice device = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(address);
+ int rssi = record[8];
+ long timestampNanos = now - parseTimestampNanos(extractBytes(record, 9, 2));
+ results.add(
+ new ScanResult(
+ device, ScanRecord.parseFromBytes(new byte[0]), rssi, timestampNanos));
+ }
+ return results;
+ }
+
+ @VisibleForTesting
+ long parseTimestampNanos(byte[] data) {
+ long timestampUnit = NumberUtils.littleEndianByteArrayToInt(data);
+ // Timestamp is in every 50 ms.
+ return TimeUnit.MILLISECONDS.toNanos(timestampUnit * 50);
+ }
+
+ private Set<ScanResult> parseFullResults(int numRecords, byte[] batchRecord) {
+ if (DBG) {
+ Log.d(TAG, "Batch record : " + Arrays.toString(batchRecord));
+ }
+ Set<ScanResult> results = new HashSet<ScanResult>(numRecords);
+ int position = 0;
+ long now = SystemClock.elapsedRealtimeNanos();
+ while (position < batchRecord.length) {
+ byte[] address = extractBytes(batchRecord, position, 6);
+ // TODO: remove temp hack.
+ reverse(address);
+ BluetoothDevice device = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(address);
+ position += 6;
+ // Skip address type.
+ position++;
+ // Skip tx power level.
+ position++;
+ int rssi = batchRecord[position++];
+ long timestampNanos = now - parseTimestampNanos(extractBytes(batchRecord, position, 2));
+ position += 2;
+
+ // Combine advertise packet and scan response packet.
+ int advertisePacketLen = batchRecord[position++];
+ byte[] advertiseBytes = extractBytes(batchRecord, position, advertisePacketLen);
+ position += advertisePacketLen;
+ int scanResponsePacketLen = batchRecord[position++];
+ byte[] scanResponseBytes = extractBytes(batchRecord, position, scanResponsePacketLen);
+ position += scanResponsePacketLen;
+ byte[] scanRecord = new byte[advertisePacketLen + scanResponsePacketLen];
+ System.arraycopy(advertiseBytes, 0, scanRecord, 0, advertisePacketLen);
+ System.arraycopy(
+ scanResponseBytes, 0, scanRecord, advertisePacketLen, scanResponsePacketLen);
+ if (DBG) {
+ Log.d(TAG, "ScanRecord : " + Arrays.toString(scanRecord));
+ }
+ results.add(
+ new ScanResult(
+ device, ScanRecord.parseFromBytes(scanRecord), rssi, timestampNanos));
+ }
+ return results;
+ }
+
+ // Reverse byte array.
+ private void reverse(byte[] address) {
+ int len = address.length;
+ for (int i = 0; i < len / 2; ++i) {
+ byte b = address[i];
+ address[i] = address[len - 1 - i];
+ address[len - 1 - i] = b;
+ }
+ }
+
+ // Helper method to extract bytes from byte array.
+ private static byte[] extractBytes(byte[] scanRecord, int start, int length) {
+ byte[] bytes = new byte[length];
+ System.arraycopy(scanRecord, start, bytes, 0, length);
+ return bytes;
+ }
+
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
+ public void onBatchScanThresholdCrossed(int clientIf) {
+ if (DBG) {
+ Log.d(TAG, "onBatchScanThresholdCrossed() - clientIf=" + clientIf);
+ }
+ flushPendingBatchResults(clientIf, mContext.getAttributionSource());
+ }
+
+ public AdvtFilterOnFoundOnLostInfo createOnTrackAdvFoundLostObject(
+ int clientIf,
+ int advPktLen,
+ byte[] advPkt,
+ int scanRspLen,
+ byte[] scanRsp,
+ int filtIndex,
+ int advState,
+ int advInfoPresent,
+ String address,
+ int addrType,
+ int txPower,
+ int rssiValue,
+ int timeStamp) {
+
+ return new AdvtFilterOnFoundOnLostInfo(
+ clientIf,
+ advPktLen,
+ advPkt,
+ scanRspLen,
+ scanRsp,
+ filtIndex,
+ advState,
+ advInfoPresent,
+ address,
+ addrType,
+ txPower,
+ rssiValue,
+ timeStamp);
+ }
+
+ public void onTrackAdvFoundLost(AdvtFilterOnFoundOnLostInfo trackingInfo)
+ throws RemoteException {
+ if (DBG) {
+ Log.d(
+ TAG,
+ "onTrackAdvFoundLost() - scannerId= "
+ + trackingInfo.getClientIf()
+ + " address = "
+ + trackingInfo.getAddress()
+ + " adv_state = "
+ + trackingInfo.getAdvState());
+ }
+
+ ScannerMap.App app = mScannerMap.getById(trackingInfo.getClientIf());
+ if (app == null || (app.callback == null && app.info == null)) {
+ Log.e(TAG, "app or callback is null");
+ return;
+ }
+
+ BluetoothDevice device =
+ BluetoothAdapter.getDefaultAdapter().getRemoteDevice(trackingInfo.getAddress());
+ int advertiserState = trackingInfo.getAdvState();
+ ScanResult result =
+ new ScanResult(
+ device,
+ ScanRecord.parseFromBytes(trackingInfo.getResult()),
+ trackingInfo.getRSSIValue(),
+ SystemClock.elapsedRealtimeNanos());
+
+ for (ScanClient client : mScanManager.getRegularScanQueue()) {
+ if (client.scannerId == trackingInfo.getClientIf()) {
+ ScanSettings settings = client.settings;
+ if ((advertiserState == ADVT_STATE_ONFOUND)
+ && ((settings.getCallbackType() & ScanSettings.CALLBACK_TYPE_FIRST_MATCH)
+ != 0)) {
+ if (app.callback != null) {
+ app.callback.onFoundOrLost(true, result);
+ } else {
+ sendResultByPendingIntent(
+ app.info, result, ScanSettings.CALLBACK_TYPE_FIRST_MATCH, client);
+ }
+ } else if ((advertiserState == ADVT_STATE_ONLOST)
+ && ((settings.getCallbackType() & ScanSettings.CALLBACK_TYPE_MATCH_LOST)
+ != 0)) {
+ if (app.callback != null) {
+ app.callback.onFoundOrLost(false, result);
+ } else {
+ sendResultByPendingIntent(
+ app.info, result, ScanSettings.CALLBACK_TYPE_MATCH_LOST, client);
+ }
+ } else {
+ if (DBG) {
+ Log.d(
+ TAG,
+ "Not reporting onlost/onfound : "
+ + advertiserState
+ + " scannerId = "
+ + client.scannerId
+ + " callbackType "
+ + settings.getCallbackType());
+ }
+ }
+ }
+ }
+ }
+
+ public void onScanParamSetupCompleted(int status, int scannerId) throws RemoteException {
+ ContextMap.App app = mScannerMap.getById(scannerId);
+ if (app == null || app.callback == null) {
+ Log.e(TAG, "Advertise app or callback is null");
+ return;
+ }
+ if (DBG) {
+ Log.d(TAG, "onScanParamSetupCompleted : " + status);
+ }
+ }
+
+ // callback from ScanManager for dispatch of errors apps.
+ public void onScanManagerErrorCallback(int scannerId, int errorCode) throws RemoteException {
+ ScannerMap.App app = mScannerMap.getById(scannerId);
+ if (app == null || (app.callback == null && app.info == null)) {
+ Log.e(TAG, "App or callback is null");
+ return;
+ }
+ if (app.callback != null) {
+ app.callback.onScanManagerErrorCallback(errorCode);
+ } else {
+ try {
+ sendErrorByPendingIntent(app.info, errorCode);
+ } catch (PendingIntent.CanceledException e) {
+ Log.e(TAG, "Error sending error code via PendingIntent:" + e);
+ }
+ }
+ }
+
+ /**************************************************************************
+ * GATT Service functions - Shared CLIENT/SERVER
+ *************************************************************************/
+
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
+ public void registerScanner(
+ IScannerCallback callback, WorkSource workSource, AttributionSource attributionSource)
+ throws RemoteException {
+ if (!Utils.checkScanPermissionForDataDelivery(
+ mContext, attributionSource, "ScanHelper registerScanner")) {
+ return;
+ }
+
+ UUID uuid = UUID.randomUUID();
+ if (DBG) {
+ Log.d(TAG, "registerScanner() - UUID=" + uuid);
+ }
+
+ enforceImpersonatationPermissionIfNeeded(workSource);
+
+ AppScanStats app = mScannerMap.getAppScanStatsByUid(Binder.getCallingUid());
+ if (app != null
+ && app.isScanningTooFrequently()
+ && !Utils.checkCallerHasPrivilegedPermission(mContext)) {
+ Log.e(TAG, "App '" + app.appName + "' is scanning too frequently");
+ callback.onScannerRegistered(ScanCallback.SCAN_FAILED_SCANNING_TOO_FREQUENTLY, -1);
+ return;
+ }
+
+ mScannerMap.add(uuid, workSource, callback, null, mContext, this);
+ mScanManager.registerScanner(uuid);
+ }
+
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
+ public void unregisterScanner(int scannerId, AttributionSource attributionSource) {
+ if (!Utils.checkScanPermissionForDataDelivery(
+ mContext, attributionSource, "ScanHelper unregisterScanner")) {
+ return;
+ }
+
+ if (DBG) {
+ Log.d(TAG, "unregisterScanner() - scannerId=" + scannerId);
+ }
+ mScannerMap.remove(scannerId);
+ mScanManager.unregisterScanner(scannerId);
+ }
+
+ private List<String> getAssociatedDevices(String callingPackage) {
+ if (mCompanionManager == null) {
+ return Collections.emptyList();
+ }
+
+ List<String> macAddresses = new ArrayList();
+
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ for (AssociationInfo info : Utils.getCdmAssociations(mCompanionManager)) {
+ if (info.getPackageName().equals(callingPackage)
+ && !info.isSelfManaged()
+ && info.getDeviceMacAddress() != null) {
+ macAddresses.add(info.getDeviceMacAddress().toString());
+ }
+ }
+ } catch (SecurityException se) {
+ // Not an app with associated devices
+ } catch (Exception e) {
+ Log.e(TAG, "Cannot check device associations for " + callingPackage, e);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ return macAddresses;
+ }
+
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
+ public void startScan(
+ int scannerId,
+ ScanSettings settings,
+ List<ScanFilter> filters,
+ AttributionSource attributionSource) {
+ if (DBG) {
+ Log.d(TAG, "start scan with filters");
+ }
+
+ if (!Utils.checkScanPermissionForDataDelivery(
+ mContext, attributionSource, "Starting GATT scan.")) {
+ return;
+ }
+
+ enforcePrivilegedPermissionIfNeeded(settings);
+ String callingPackage = attributionSource.getPackageName();
+ settings = enforceReportDelayFloor(settings);
+ enforcePrivilegedPermissionIfNeeded(filters);
+ final ScanClient scanClient = new ScanClient(scannerId, settings, filters);
+ scanClient.userHandle = Binder.getCallingUserHandle();
+ mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
+ scanClient.eligibleForSanitizedExposureNotification =
+ callingPackage.equals(mExposureNotificationPackage);
+
+ scanClient.hasDisavowedLocation =
+ Utils.hasDisavowedLocationForScan(
+ mContext, attributionSource, mTestModeAccessor.isTestModeEnabled());
+
+ scanClient.isQApp = checkCallerTargetSdk(mContext, callingPackage, Build.VERSION_CODES.Q);
+ if (!scanClient.hasDisavowedLocation) {
+ if (scanClient.isQApp) {
+ scanClient.hasLocationPermission =
+ Utils.checkCallerHasFineLocation(
+ mContext, attributionSource, scanClient.userHandle);
+ } else {
+ scanClient.hasLocationPermission =
+ Utils.checkCallerHasCoarseOrFineLocation(
+ mContext, attributionSource, scanClient.userHandle);
+ }
+ }
+ scanClient.hasNetworkSettingsPermission =
+ Utils.checkCallerHasNetworkSettingsPermission(mContext);
+ scanClient.hasNetworkSetupWizardPermission =
+ Utils.checkCallerHasNetworkSetupWizardPermission(mContext);
+ scanClient.hasScanWithoutLocationPermission =
+ Utils.checkCallerHasScanWithoutLocationPermission(mContext);
+ scanClient.associatedDevices = getAssociatedDevices(callingPackage);
+
+ AppScanStats app = mScannerMap.getAppScanStatsById(scannerId);
+ ContextMap.App cbApp = mScannerMap.getById(scannerId);
+ if (app != null) {
+ scanClient.stats = app;
+ boolean isFilteredScan = (filters != null) && !filters.isEmpty();
+ boolean isCallbackScan = false;
+ if (cbApp != null) {
+ isCallbackScan = cbApp.callback != null;
+ }
+ app.recordScanStart(settings, filters, isFilteredScan, isCallbackScan, scannerId);
+ }
+
+ mScanManager.startScan(scanClient);
+ }
+
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
+ public void registerPiAndStartScan(
+ PendingIntent pendingIntent,
+ ScanSettings settings,
+ List<ScanFilter> filters,
+ AttributionSource attributionSource) {
+ if (DBG) {
+ Log.d(TAG, "start scan with filters, for PendingIntent");
+ }
+
+ if (!Utils.checkScanPermissionForDataDelivery(
+ mContext, attributionSource, "Starting GATT scan.")) {
+ return;
+ }
+ enforcePrivilegedPermissionIfNeeded(settings);
+ settings = enforceReportDelayFloor(settings);
+ enforcePrivilegedPermissionIfNeeded(filters);
+ UUID uuid = UUID.randomUUID();
+ String callingPackage = attributionSource.getPackageName();
+ int callingUid = attributionSource.getUid();
+ PendingIntentInfo piInfo = new PendingIntentInfo();
+ piInfo.intent = pendingIntent;
+ piInfo.settings = settings;
+ piInfo.filters = filters;
+ piInfo.callingPackage = callingPackage;
+ piInfo.callingUid = callingUid;
+ if (DBG) {
+ Log.d(
+ TAG,
+ "startScan(PI) -"
+ + (" UUID=" + uuid)
+ + (" Package=" + callingPackage)
+ + (" UID=" + callingUid));
+ }
+
+ // Don't start scan if the Pi scan already in mScannerMap.
+ if (mScannerMap.getByContextInfo(piInfo) != null) {
+ Log.d(TAG, "Don't startScan(PI) since the same Pi scan already in mScannerMap.");
+ return;
+ }
+
+ ContextMap.App app = mScannerMap.add(uuid, null, null, piInfo, mContext, this);
+
+ app.mUserHandle = UserHandle.getUserHandleForUid(Binder.getCallingUid());
+ mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
+ app.mEligibleForSanitizedExposureNotification =
+ callingPackage.equals(mExposureNotificationPackage);
+
+ app.mHasDisavowedLocation =
+ Utils.hasDisavowedLocationForScan(
+ mContext, attributionSource, mTestModeAccessor.isTestModeEnabled());
+
+ if (!app.mHasDisavowedLocation) {
+ try {
+ if (checkCallerTargetSdk(mContext, callingPackage, Build.VERSION_CODES.Q)) {
+ app.hasLocationPermission =
+ Utils.checkCallerHasFineLocation(
+ mContext, attributionSource, app.mUserHandle);
+ } else {
+ app.hasLocationPermission =
+ Utils.checkCallerHasCoarseOrFineLocation(
+ mContext, attributionSource, app.mUserHandle);
+ }
+ } catch (SecurityException se) {
+ // No need to throw here. Just mark as not granted.
+ app.hasLocationPermission = false;
+ }
+ }
+ app.mHasNetworkSettingsPermission = Utils.checkCallerHasNetworkSettingsPermission(mContext);
+ app.mHasNetworkSetupWizardPermission =
+ Utils.checkCallerHasNetworkSetupWizardPermission(mContext);
+ app.mHasScanWithoutLocationPermission =
+ Utils.checkCallerHasScanWithoutLocationPermission(mContext);
+ app.mAssociatedDevices = getAssociatedDevices(callingPackage);
+ mScanManager.registerScanner(uuid);
+
+ // If this fails, we should stop the scan immediately.
+ if (!pendingIntent.addCancelListener(Runnable::run, mScanIntentCancelListener)) {
+ Log.d(TAG, "scanning PendingIntent is already cancelled, stopping scan.");
+ stopScan(pendingIntent, attributionSource);
+ }
+ }
+
+ public void continuePiStartScan(int scannerId, ScannerMap.App app) {
+ final PendingIntentInfo piInfo = app.info;
+ final ScanClient scanClient =
+ new ScanClient(scannerId, piInfo.settings, piInfo.filters, piInfo.callingUid);
+ scanClient.hasLocationPermission = app.hasLocationPermission;
+ scanClient.userHandle = app.mUserHandle;
+ scanClient.isQApp = checkCallerTargetSdk(mContext, app.name, Build.VERSION_CODES.Q);
+ scanClient.eligibleForSanitizedExposureNotification =
+ app.mEligibleForSanitizedExposureNotification;
+ scanClient.hasNetworkSettingsPermission = app.mHasNetworkSettingsPermission;
+ scanClient.hasNetworkSetupWizardPermission = app.mHasNetworkSetupWizardPermission;
+ scanClient.hasScanWithoutLocationPermission = app.mHasScanWithoutLocationPermission;
+ scanClient.associatedDevices = app.mAssociatedDevices;
+ scanClient.hasDisavowedLocation = app.mHasDisavowedLocation;
+
+ AppScanStats scanStats = mScannerMap.getAppScanStatsById(scannerId);
+ if (scanStats != null) {
+ scanClient.stats = scanStats;
+ boolean isFilteredScan = (piInfo.filters != null) && !piInfo.filters.isEmpty();
+ scanStats.recordScanStart(
+ piInfo.settings, piInfo.filters, isFilteredScan, false, scannerId);
+ }
+
+ mScanManager.startScan(scanClient);
+ }
+
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
+ public void flushPendingBatchResults(int scannerId, AttributionSource attributionSource) {
+ if (!Utils.checkScanPermissionForDataDelivery(
+ mContext, attributionSource, "ScanHelper flushPendingBatchResults")) {
+ return;
+ }
+ if (DBG) {
+ Log.d(TAG, "flushPendingBatchResults - scannerId=" + scannerId);
+ }
+ mScanManager.flushBatchScanResults(new ScanClient(scannerId));
+ }
+
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
+ public void stopScan(int scannerId, AttributionSource attributionSource) {
+ if (!Utils.checkScanPermissionForDataDelivery(
+ mContext, attributionSource, "ScanHelper stopScan")) {
+ return;
+ }
+ int scanQueueSize =
+ mScanManager.getBatchScanQueue().size() + mScanManager.getRegularScanQueue().size();
+ if (DBG) {
+ Log.d(TAG, "stopScan() - queue size =" + scanQueueSize);
+ }
+
+ AppScanStats app = null;
+ app = mScannerMap.getAppScanStatsById(scannerId);
+ if (app != null) {
+ app.recordScanStop(scannerId);
+ }
+
+ mScanManager.stopScan(scannerId);
+ }
+
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
+ public void stopScan(PendingIntent intent, AttributionSource attributionSource) {
+ if (!Utils.checkScanPermissionForDataDelivery(
+ mContext, attributionSource, "ScanHelper stopScan")) {
+ return;
+ }
+ PendingIntentInfo pii = new PendingIntentInfo();
+ pii.intent = intent;
+ ContextMap.App app = mScannerMap.getByContextInfo(pii);
+ if (VDBG) {
+ Log.d(TAG, "stopScan(PendingIntent): app found = " + app);
+ }
+ if (app != null) {
+ intent.removeCancelListener(mScanIntentCancelListener);
+ final int scannerId = app.id;
+ stopScan(scannerId, attributionSource);
+ // Also unregister the scanner
+ unregisterScanner(scannerId, attributionSource);
+ }
+ }
+
+ /**************************************************************************
+ * PERIODIC SCANNING
+ *************************************************************************/
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
+ public void registerSync(
+ ScanResult scanResult,
+ int skip,
+ int timeout,
+ IPeriodicAdvertisingCallback callback,
+ AttributionSource attributionSource) {
+ if (!Utils.checkScanPermissionForDataDelivery(
+ mContext, attributionSource, "ScanHelper registerSync")) {
+ return;
+ }
+ mPeriodicScanManager.startSync(scanResult, skip, timeout, callback);
+ }
+
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
+ public void unregisterSync(
+ IPeriodicAdvertisingCallback callback, AttributionSource attributionSource) {
+ if (!Utils.checkScanPermissionForDataDelivery(
+ mContext, attributionSource, "ScanHelper unregisterSync")) {
+ return;
+ }
+ mPeriodicScanManager.stopSync(callback);
+ }
+
+ public void transferSync(
+ BluetoothDevice bda,
+ int serviceData,
+ int syncHandle,
+ AttributionSource attributionSource) {
+ if (!Utils.checkScanPermissionForDataDelivery(
+ mContext, attributionSource, "ScanHelper transferSync")) {
+ return;
+ }
+ mPeriodicScanManager.transferSync(bda, serviceData, syncHandle);
+ }
+
+ public void transferSetInfo(
+ BluetoothDevice bda,
+ int serviceData,
+ int advHandle,
+ IPeriodicAdvertisingCallback callback,
+ AttributionSource attributionSource) {
+ if (!Utils.checkScanPermissionForDataDelivery(
+ mContext, attributionSource, "ScanHelper transferSetInfo")) {
+ return;
+ }
+ mPeriodicScanManager.transferSetInfo(bda, serviceData, advHandle, callback);
+ }
+
+ /**
+ * DeathRecipient handler used to unregister applications that disconnect ungracefully (ie.
+ * crash or forced close).
+ */
+ class ScannerDeathRecipient implements IBinder.DeathRecipient {
+ int mScannerId;
+ private String mPackageName;
+
+ ScannerDeathRecipient(int scannerId, String packageName) {
+ mScannerId = scannerId;
+ mPackageName = packageName;
+ }
+
+ @Override
+ public void binderDied() {
+ if (DBG) {
+ Log.d(
+ TAG,
+ "Binder is dead - unregistering scanner ("
+ + mPackageName
+ + " "
+ + mScannerId
+ + ")!");
+ }
+
+ ScanClient client = getScanClient(mScannerId);
+ if (client != null) {
+ if (Flags.leScanFixRemoteException()) {
+ handleDeadScanClient(client);
+ } else {
+ client.appDied = true;
+ stopScan(client.scannerId, mContext.getAttributionSource());
+ }
+ }
+ }
+
+ private ScanClient getScanClient(int clientIf) {
+ for (ScanClient client : mScanManager.getRegularScanQueue()) {
+ if (client.scannerId == clientIf) {
+ return client;
+ }
+ }
+ for (ScanClient client : mScanManager.getBatchScanQueue()) {
+ if (client.scannerId == clientIf) {
+ return client;
+ }
+ }
+ return null;
+ }
+ }
+
+ private boolean needsPrivilegedPermissionForScan(ScanSettings settings) {
+ // BLE scan only mode needs special permission.
+ if (mAdapterService.getState() != BluetoothAdapter.STATE_ON) {
+ return true;
+ }
+
+ // Regular scan, no special permission.
+ if (settings == null) {
+ return false;
+ }
+
+ // Ambient discovery mode, needs privileged permission.
+ if (settings.getScanMode() == ScanSettings.SCAN_MODE_AMBIENT_DISCOVERY) {
+ return true;
+ }
+
+ // Regular scan, no special permission.
+ if (settings.getReportDelayMillis() == 0) {
+ return false;
+ }
+
+ // Batch scan, truncated mode needs permission.
+ return settings.getScanResultType() == ScanSettings.SCAN_RESULT_TYPE_ABBREVIATED;
+ }
+
+ /*
+ * The {@link ScanFilter#setDeviceAddress} API overloads are @SystemApi access methods. This
+ * requires that the permissions be BLUETOOTH_PRIVILEGED.
+ */
+ @SuppressLint("AndroidFrameworkRequiresPermission")
+ private void enforcePrivilegedPermissionIfNeeded(List<ScanFilter> filters) {
+ if (DBG) {
+ Log.d(TAG, "enforcePrivilegedPermissionIfNeeded(" + filters + ")");
+ }
+ // Some 3p API cases may have null filters, need to allow
+ if (filters != null) {
+ for (ScanFilter filter : filters) {
+ // The only case to enforce here is if there is an address
+ // If there is an address, enforce if the correct combination criteria is met.
+ if (filter.getDeviceAddress() != null) {
+ // At this point we have an address, that means a caller used the
+ // setDeviceAddress(address) public API for the ScanFilter
+ // We don't want to enforce if the type is PUBLIC and the IRK is null
+ // However, if we have a different type that means the caller used a new
+ // @SystemApi such as setDeviceAddress(address, type) or
+ // setDeviceAddress(address, type, irk) which are both @SystemApi and require
+ // permissions to be enforced
+ if (filter.getAddressType() == BluetoothDevice.ADDRESS_TYPE_PUBLIC
+ && filter.getIrk() == null) {
+ // Do not enforce
+ } else {
+ enforceBluetoothPrivilegedPermission(mContext);
+ }
+ }
+ }
+ }
+ }
+
+ @SuppressLint("AndroidFrameworkRequiresPermission")
+ private void enforcePrivilegedPermissionIfNeeded(ScanSettings settings) {
+ if (needsPrivilegedPermissionForScan(settings)) {
+ enforceBluetoothPrivilegedPermission(mContext);
+ }
+ }
+
+ // Enforce caller has UPDATE_DEVICE_STATS permission, which allows the caller to blame other
+ // apps for Bluetooth usage. A {@link SecurityException} will be thrown if the caller app does
+ // not have UPDATE_DEVICE_STATS permission.
+ @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS)
+ private void enforceImpersonatationPermission() {
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.UPDATE_DEVICE_STATS,
+ "Need UPDATE_DEVICE_STATS permission");
+ }
+
+ @SuppressLint("AndroidFrameworkRequiresPermission")
+ private void enforceImpersonatationPermissionIfNeeded(WorkSource workSource) {
+ if (workSource != null) {
+ enforceImpersonatationPermission();
+ }
+ }
+
+ /**
+ * Ensures the report delay is either 0 or at least the floor value (5000ms)
+ *
+ * @param settings are the scan settings passed into a request to start le scanning
+ * @return the passed in ScanSettings object if the report delay is 0 or above the floor value;
+ * a new ScanSettings object with the report delay being the floor value if the original
+ * report delay was between 0 and the floor value (exclusive of both)
+ */
+ @VisibleForTesting
+ ScanSettings enforceReportDelayFloor(ScanSettings settings) {
+ if (settings.getReportDelayMillis() == 0) {
+ return settings;
+ }
+
+ // Need to clear identity to pass device config permission check
+ final long callerToken = Binder.clearCallingIdentity();
+ try {
+ long floor =
+ DeviceConfig.getLong(
+ DeviceConfig.NAMESPACE_BLUETOOTH,
+ "report_delay",
+ DEFAULT_REPORT_DELAY_FLOOR);
+
+ if (settings.getReportDelayMillis() > floor) {
+ return settings;
+ } else {
+ return new ScanSettings.Builder()
+ .setCallbackType(settings.getCallbackType())
+ .setLegacy(settings.getLegacy())
+ .setMatchMode(settings.getMatchMode())
+ .setNumOfMatches(settings.getNumOfMatches())
+ .setPhy(settings.getPhy())
+ .setReportDelay(floor)
+ .setScanMode(settings.getScanMode())
+ .setScanResultType(settings.getScanResultType())
+ .build();
+ }
+ } finally {
+ Binder.restoreCallingIdentity(callerToken);
+ }
+ }
+
+ public void addScanEvent(BluetoothMetricsProto.ScanEvent event) {
+ synchronized (mScanEvents) {
+ if (mScanEvents.size() == NUM_SCAN_EVENTS_KEPT) {
+ mScanEvents.remove();
+ }
+ mScanEvents.add(event);
+ }
+ }
+
+ public void dumpProto(BluetoothMetricsProto.BluetoothLog.Builder builder) {
+ synchronized (mScanEvents) {
+ builder.addAllScanEvent(mScanEvents);
+ }
+ }
}
diff --git a/android/app/tests/robotests/src/com/android/bluetooth/opp/OppSendFileInfoTest.java b/android/app/tests/robotests/src/com/android/bluetooth/opp/OppSendFileInfoTest.java
index 22a4284ae1..ea712ef84c 100644
--- a/android/app/tests/robotests/src/com/android/bluetooth/opp/OppSendFileInfoTest.java
+++ b/android/app/tests/robotests/src/com/android/bluetooth/opp/OppSendFileInfoTest.java
@@ -26,11 +26,12 @@ import android.content.ContentResolver;
import android.content.Context;
import android.net.Uri;
-import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import org.robolectric.RobolectricTestRunner;
import java.io.FileInputStream;
@@ -43,15 +44,12 @@ public class OppSendFileInfoTest {
private static final int TEST_FILE_SIZE = 10;
private static final int MAXIMUM_FILE_SIZE = 0xFFFFFFFF;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock private Context mContext;
@Mock private ContentResolver mContentResolver;
@Mock private FileInputStream mFileInputStream;
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
- }
-
/**
* Test a BluetoothOppSendFileInfo generated from a local file (MIME type: text/plain,
* size: #TEST_FILE_SIZE).
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 52f2736345..97cf8e0f86 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
@@ -34,10 +34,12 @@ import com.android.bluetooth.R;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.util.Arrays;
@@ -49,6 +51,8 @@ public class A2dpCodecConfigTest {
private BluetoothDevice mTestDevice;
private A2dpCodecConfig mA2dpCodecConfig;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock private Context mMockContext;
@Mock private Resources mMockResources;
@Mock private A2dpNativeInterface mA2dpNativeInterface;
@@ -159,8 +163,6 @@ public class A2dpCodecConfigTest {
@Before
public void setUp() throws Exception {
- // Set up mocks and test assets
- MockitoAnnotations.initMocks(this);
mTargetContext = InstrumentationRegistry.getTargetContext();
when(mMockContext.getResources()).thenReturn(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 58655f6a2c..cc7a361d3b 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
@@ -45,7 +45,8 @@ import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.util.List;
@@ -56,6 +57,8 @@ public class A2dpServiceBinderTest {
@Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock private A2dpService mA2dpService;
@Mock private AudioRoutingManager mAudioRoutingManager;
@Mock private PackageManager mPackageManager;
@@ -64,7 +67,6 @@ public class A2dpServiceBinderTest {
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
doReturn(mAudioRoutingManager).when(mA2dpService).getActiveDeviceManager();
doReturn(mPackageManager).when(mA2dpService).getPackageManager();
ApplicationInfo appInfo = new ApplicationInfo();
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 857c663b28..21d4645798 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
@@ -50,13 +50,15 @@ import org.hamcrest.core.AllOf;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.InOrder;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
import org.mockito.hamcrest.MockitoHamcrest;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.time.Duration;
import java.util.Arrays;
@@ -72,6 +74,8 @@ public class A2dpServiceTest {
private static final BluetoothDevice sTestDevice =
sAdapter.getRemoteDevice("00:01:02:03:04:05");
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock private A2dpNativeInterface mMockNativeInterface;
@Mock private ActiveDeviceManager mActiveDeviceManager;
@Mock private AdapterService mAdapterService;
@@ -84,8 +88,6 @@ public class A2dpServiceTest {
@Before
public void setUp() throws Exception {
- // Set up mocks and test assets
- MockitoAnnotations.initMocks(this);
mInOrder = inOrder(mAdapterService);
TestUtils.mockGetSystemService(
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 0c6fdc6936..98cee48f89 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
@@ -42,11 +42,13 @@ import org.hamcrest.core.IsInstanceOf;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.util.Arrays;
@@ -64,6 +66,8 @@ public class A2dpStateMachineTest {
private BluetoothCodecConfig mCodecConfigAac;
private BluetoothCodecConfig mCodecConfigOpus;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock private AdapterService mAdapterService;
@Mock private ActiveDeviceManager mActiveDeviceManager;
@Mock private SilenceDeviceManager mSilenceDeviceManager;
@@ -73,8 +77,6 @@ public class A2dpStateMachineTest {
@Before
public void setUp() throws Exception {
mTargetContext = InstrumentationRegistry.getTargetContext();
- // Set up mocks and test assets
- MockitoAnnotations.initMocks(this);
doReturn(mActiveDeviceManager).when(mAdapterService).getActiveDeviceManager();
doReturn(mSilenceDeviceManager).when(mAdapterService).getSilenceDeviceManager();
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 0d1650ee00..23641be621 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
@@ -29,20 +29,23 @@ import com.android.bluetooth.x.com.android.modules.utils.SynchronousResultReceiv
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.util.List;
public class A2dpSinkServiceBinderTest {
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock private A2dpSinkService mService;
private A2dpSinkService.A2dpSinkServiceBinder mBinder;
private BluetoothAdapter mAdapter;
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
mAdapter = BluetoothAdapter.getDefaultAdapter();
mBinder = new A2dpSinkService.A2dpSinkServiceBinder(mService);
}
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 6f546daa9d..d19e6aa5a9 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
@@ -43,7 +43,8 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.util.ArrayList;
import java.util.List;
@@ -57,6 +58,8 @@ public class A2dpSinkServiceTest {
@Rule public final ServiceTestRule mServiceRule = new ServiceTestRule();
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock private AdapterService mAdapterService;
@Mock private DatabaseManager mDatabaseManager;
@Mock private A2dpSinkNativeInterface mNativeInterface;
@@ -76,7 +79,6 @@ public class A2dpSinkServiceTest {
@Before
public void setUp() throws Exception {
mTargetContext = InstrumentationRegistry.getTargetContext();
- MockitoAnnotations.initMocks(this);
mLooper = new TestLooper();
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 03d95a3a77..aac7f7f675 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
@@ -38,16 +38,20 @@ import com.android.bluetooth.TestUtils;
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
@RunWith(AndroidJUnit4.class)
public class A2dpSinkStateMachineTest {
private static final String DEVICE_ADDRESS = "11:11:11:11:11:11";
private static final int UNHANDLED_MESSAGE = 9999;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock private A2dpSinkService mService;
@Mock private A2dpSinkNativeInterface mNativeInterface;
@@ -60,7 +64,6 @@ public class A2dpSinkStateMachineTest {
@Before
public void setUp() throws Exception {
mTargetContext = InstrumentationRegistry.getTargetContext();
- MockitoAnnotations.initMocks(this);
mLooper = new TestLooper();
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 4b25bbba1d..fe49e05bf6 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
@@ -45,7 +45,8 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
@MediumTest
@RunWith(AndroidJUnit4.class)
@@ -56,6 +57,8 @@ public class A2dpSinkStreamHandlerTest {
private A2dpSinkStreamHandler mStreamHandler;
private Context mTargetContext;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock private A2dpSinkService mMockA2dpSink;
@Mock private A2dpSinkNativeInterface mMockNativeInterface;
@@ -76,7 +79,6 @@ public class A2dpSinkStreamHandlerTest {
@Before
public void setUp() throws Exception {
mTargetContext = InstrumentationRegistry.getTargetContext();
- MockitoAnnotations.initMocks(this);
// Mock the looper
if (Looper.myLooper() == null) {
Looper.prepare();
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 5d4f49d98c..c2426563b5 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
@@ -33,10 +33,12 @@ import androidx.test.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.util.ArrayList;
import java.util.Collections;
@@ -51,11 +53,12 @@ public final class BrowsablePlayerConnectorTest {
Context mContext;
TestLooper mTestLooper;
List<ResolveInfo> mPlayerList;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock MediaBrowser mMediaBrowser;
MediaBrowser.ConnectionCallback mConnectionCallback;
@Before
public void setUp() {
- MockitoAnnotations.initMocks(this);
mContext = InstrumentationRegistry.getTargetContext();
mTestLooper = new TestLooper();
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 c5d6fd22d2..dcf1b069d9 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
@@ -44,12 +44,14 @@ import com.android.bluetooth.TestUtils;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.io.InputStream;
import java.util.ArrayList;
@@ -64,6 +66,8 @@ public class BrowserPlayerWrapperTest {
@Captor ArgumentCaptor<MediaController.Callback> mControllerCb;
@Captor ArgumentCaptor<Handler> mTimeoutHandler;
@Captor ArgumentCaptor<List<ListItem>> mWrapperBrowseCb;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock MediaBrowser mMockBrowser;
@Mock BrowsedPlayerWrapper.ConnectionCallback mConnCb;
@Mock BrowsedPlayerWrapper.BrowseCallback mBrowseCb;
@@ -91,7 +95,6 @@ public class BrowserPlayerWrapperTest {
@Before
public void setUp() {
- MockitoAnnotations.initMocks(this);
mTargetContext = InstrumentationRegistry.getTargetContext();
mTestResources = TestUtils.getTestApplicationResources(mTargetContext);
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 7e2106b5eb..4d7d339d86 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
@@ -41,10 +41,12 @@ import com.android.bluetooth.TestUtils;
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.io.InputStream;
@@ -52,6 +54,8 @@ import java.io.InputStream;
public class ImageTest {
private Context mTargetContext;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
private @Mock Context mMockContext;
private @Mock Resources mMockResources;
private Resources mTestResources;
@@ -78,7 +82,6 @@ public class ImageTest {
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
mTargetContext = InstrumentationRegistry.getTargetContext();
mTestResources = TestUtils.getTestApplicationResources(mTargetContext);
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 353e6badba..6b7af24254 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
@@ -33,12 +33,14 @@ import androidx.test.runner.AndroidJUnit4;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.util.ArrayList;
@@ -50,6 +52,8 @@ public class MediaPlayerListTest {
private @Captor ArgumentCaptor<AudioManager.AudioPlaybackCallback> mAudioCb;
private @Captor ArgumentCaptor<MediaPlayerWrapper.Callback> mPlayerWrapperCb;
private @Captor ArgumentCaptor<MediaData> mMediaUpdateData;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
private @Mock Context mMockContext;
private @Mock MediaPlayerList.MediaUpdateCallback mMediaUpdateCallback;
private @Mock MediaController mMockController;
@@ -70,7 +74,6 @@ public class MediaPlayerListTest {
}
Assert.assertNotNull(Looper.myLooper());
- MockitoAnnotations.initMocks(this);
AudioManager mockAudioManager = mock(AudioManager.class);
when(mMockContext.getSystemService(Context.AUDIO_SERVICE)).thenReturn(mockAudioManager);
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 9ed1fa0c96..4503968683 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
@@ -41,12 +41,14 @@ import com.android.bluetooth.TestUtils;
import org.junit.Assert;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.io.InputStream;
import java.util.ArrayList;
@@ -68,6 +70,8 @@ public class MediaPlayerWrapperTest {
@Captor ArgumentCaptor<MediaController.Callback> mControllerCbs;
@Captor ArgumentCaptor<MediaData> mMediaUpdateData;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock Log.TerribleFailureHandler mFailHandler;
@Mock MediaController mMockController;
@Mock MediaPlayerWrapper.Callback mTestCbs;
@@ -89,7 +93,6 @@ public class MediaPlayerWrapperTest {
@Before
public void setUp() {
- MockitoAnnotations.initMocks(this);
mTestResources = TestUtils.getTestApplicationResources(
InstrumentationRegistry.getTargetContext());
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 f36b13bf20..8b8940815e 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
@@ -44,10 +44,12 @@ import com.android.bluetooth.TestUtils;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.io.InputStream;
@@ -55,6 +57,8 @@ import java.io.InputStream;
public class MetadataTest {
private Context mTargetContext;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
private @Mock Context mMockContext;
private @Mock Resources mMockResources;
private Resources mTestResources;
@@ -88,7 +92,6 @@ public class MetadataTest {
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
mTargetContext = InstrumentationRegistry.getTargetContext();
mTestResources = TestUtils.getTestApplicationResources(mTargetContext);
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 0a187f294b..d79e16ff18 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
@@ -37,11 +37,13 @@ import androidx.test.runner.AndroidJUnit4;
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
@SmallTest
@RunWith(AndroidJUnit4.class)
@@ -49,6 +51,8 @@ public class AvrcpVolumeManagerTest {
private static final String REMOTE_DEVICE_ADDRESS = "00:01:02:03:04:05";
private static final int TEST_DEVICE_MAX_VOUME = 25;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock
AvrcpNativeInterface mNativeInterface;
@@ -61,7 +65,6 @@ public class AvrcpVolumeManagerTest {
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
mContext = InstrumentationRegistry.getTargetContext();
when(mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC))
.thenReturn(TEST_DEVICE_MAX_VOUME);
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 e3dd565833..ee6481b197 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
@@ -40,7 +40,8 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
@SmallTest
@RunWith(AndroidJUnit4.class)
@@ -50,6 +51,8 @@ public class AvrcpBipClientTest {
@Rule
public final ServiceTestRule mBluetoothBrowserMediaServiceTestRule = new ServiceTestRule();
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock private AdapterService mAdapterService;
@Mock private AvrcpControllerNativeInterface mNativeInterface;
@@ -62,7 +65,6 @@ public class AvrcpBipClientTest {
@Before
public void setUp() throws Exception {
Context targetContext = InstrumentationRegistry.getTargetContext();
- MockitoAnnotations.initMocks(this);
TestUtils.setAdapterService(mAdapterService);
AvrcpControllerNativeInterface.setInstance(mNativeInterface);
mService = new AvrcpControllerService(targetContext, mNativeInterface);
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 c30d989a13..97117a2f85 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
@@ -28,16 +28,20 @@ import androidx.test.runner.AndroidJUnit4;
import com.android.bluetooth.x.com.android.modules.utils.SynchronousResultReceiver;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
@SmallTest
@RunWith(AndroidJUnit4.class)
public class AvrcpControllerServiceBinderTest {
private static final String REMOTE_DEVICE_ADDRESS = "00:00:00:00:00:00";
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock
private AvrcpControllerService mService;
@@ -47,7 +51,6 @@ public class AvrcpControllerServiceBinderTest {
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
mRemoteDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(REMOTE_DEVICE_ADDRESS);
mBinder = new AvrcpControllerService.AvrcpControllerServiceBinder(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 19b8f6c95e..f74372bca1 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
@@ -49,7 +49,8 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.util.ArrayList;
import java.util.Arrays;
@@ -67,6 +68,8 @@ public class AvrcpControllerServiceTest {
@Rule
public final ServiceTestRule mBluetoothBrowserMediaServiceTestRule = new ServiceTestRule();
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock private AdapterService mAdapterService;
@Mock private AvrcpControllerStateMachine mStateMachine;
@Mock private AvrcpControllerNativeInterface mNativeInterface;
@@ -76,7 +79,6 @@ public class AvrcpControllerServiceTest {
@Before
public void setUp() throws Exception {
Context targetContext = InstrumentationRegistry.getTargetContext();
- MockitoAnnotations.initMocks(this);
TestUtils.setAdapterService(mAdapterService);
AvrcpControllerNativeInterface.setInstance(mNativeInterface);
mService = new AvrcpControllerService(targetContext, mNativeInterface);
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 d01d565524..e8181d283f 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
@@ -56,7 +56,8 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.util.ArrayList;
import java.util.List;
@@ -74,6 +75,8 @@ public class AvrcpControllerStateMachineTest {
@Rule public final ServiceTestRule mAvrcpServiceRule = new ServiceTestRule();
@Rule public final ServiceTestRule mA2dpServiceRule = new ServiceTestRule();
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock private AdapterService mA2dpAdapterService;
@Mock private AdapterService mAvrcpAdapterService;
@Mock private A2dpSinkService mA2dpSinkService;
@@ -97,7 +100,6 @@ public class AvrcpControllerStateMachineTest {
}
Assert.assertNotNull(Looper.myLooper());
- MockitoAnnotations.initMocks(this);
// Start a real A2dpSinkService so we can replace the static instance with our mock
doReturn(mDatabaseManager).when(mA2dpAdapterService).getDatabase();
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 d55695d949..ddddbd08fe 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
@@ -38,7 +38,8 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.io.FileNotFoundException;
@@ -55,13 +56,14 @@ public class AvrcpCoverArtProviderTest {
@Rule
public final ServiceTestRule mServiceRule = new ServiceTestRule();
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock private Uri mUri;
@Mock private AdapterService mAdapterService;
@Mock private AvrcpControllerNativeInterface mNativeInterface;
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
TestUtils.setAdapterService(mAdapterService);
AvrcpControllerNativeInterface.setInstance(mNativeInterface);
mAdapter = BluetoothAdapter.getDefaultAdapter();
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 30e9c62132..4f6b44d55a 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
@@ -26,9 +26,11 @@ import android.net.Uri;
import android.support.v4.media.session.PlaybackStateCompat;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
public class AvrcpPlayerTest {
private static final int TEST_PLAYER_ID = 1;
@@ -44,12 +46,13 @@ public class AvrcpPlayerTest {
private BluetoothAdapter mAdapter;
private BluetoothDevice mTestDevice = null;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock
private PlayerApplicationSettings mPlayerApplicationSettings;
@Before
public void setUp() {
- MockitoAnnotations.initMocks(this);
mAdapter = BluetoothAdapter.getDefaultAdapter();
mTestDevice = mAdapter.getRemoteDevice(mTestAddress);
}
diff --git a/android/app/tests/unit/src/com/android/bluetooth/bas/BatteryServiceBinderTest.java b/android/app/tests/unit/src/com/android/bluetooth/bas/BatteryServiceBinderTest.java
index 91b6af8ad1..cdc9de99f0 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/bas/BatteryServiceBinderTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/bas/BatteryServiceBinderTest.java
@@ -28,13 +28,17 @@ import com.android.bluetooth.x.com.android.modules.utils.SynchronousResultReceiv
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.util.List;
public class BatteryServiceBinderTest {
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock
private BatteryService mService;
private BatteryService.BluetoothBatteryBinder mBinder;
@@ -42,7 +46,6 @@ public class BatteryServiceBinderTest {
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
mAdapter = BluetoothAdapter.getDefaultAdapter();
mBinder = new BatteryService.BluetoothBatteryBinder(mService);
}
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 7d7fb8aa6d..a4b11d38e5 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
@@ -74,13 +74,15 @@ import com.android.bluetooth.le_audio.LeAudioService;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.util.ArrayList;
import java.util.Arrays;
@@ -140,6 +142,8 @@ public class BassClientServiceTest {
private BassIntentReceiver mBassIntentReceiver;
@Spy private BassObjectsFactory mObjectsFactory = BassObjectsFactory.getInstance();
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock private AdapterService mAdapterService;
@Mock private DatabaseManager mDatabaseManager;
@Mock private BluetoothLeScannerWrapper mBluetoothLeScannerWrapper;
@@ -200,7 +204,6 @@ public class BassClientServiceTest {
}
mTargetContext = InstrumentationRegistry.getTargetContext();
- MockitoAnnotations.initMocks(this);
TestUtils.setAdapterService(mAdapterService);
BassObjectsFactory.setInstanceForTesting(mObjectsFactory);
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 678b6b1a02..0f7034a075 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
@@ -34,12 +34,14 @@ import android.bluetooth.le.ScanFilter;
import com.android.bluetooth.TestUtils;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.mockito.Mock;
import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.util.Collections;
import java.util.List;
@@ -47,6 +49,8 @@ import java.util.List;
@RunWith(JUnit4.class)
public class BleBroadcastAssistantBinderTest {
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock private BassClientService mService;
private BassClientService.BluetoothLeBroadcastAssistantBinder mBinder;
@@ -54,7 +58,6 @@ public class BleBroadcastAssistantBinderTest {
@Before
public void setUp() {
- MockitoAnnotations.initMocks(this);
mBinder = new BassClientService.BluetoothLeBroadcastAssistantBinder(mService);
mAdapter = BluetoothAdapter.getDefaultAdapter();
}
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 7cc9aecb6c..b344a37fb6 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
@@ -67,8 +67,9 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.util.ArrayList;
import java.util.List;
@@ -100,6 +101,8 @@ public class ActiveDeviceManagerTest {
private TestLooper mTestLooper;
@Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock private AdapterService mAdapterService;
@Mock private ServiceFactory mServiceFactory;
@Mock private A2dpService mA2dpService;
@@ -111,8 +114,6 @@ public class ActiveDeviceManagerTest {
@Before
public void setUp() throws Exception {
- // Set up mocks and test assets
- MockitoAnnotations.initMocks(this);
mTestLooper = new TestLooper();
BluetoothMethodProxy.setInstanceForTesting(mMethodProxy);
doReturn(mTestLooper.getLooper()).when(mMethodProxy).handlerThreadGetLooper(any());
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 436151b46d..2b7283ed34 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
@@ -36,11 +36,13 @@ import androidx.test.runner.AndroidJUnit4;
import com.android.bluetooth.Utils;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
@MediumTest
@RunWith(AndroidJUnit4.class)
@@ -54,6 +56,8 @@ public class AdapterPropertiesTest {
private HandlerThread mHandlerThread;
private Context mTargetContext;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock private AdapterService mAdapterService;
@Mock private AdapterNativeInterface mNativeInterface;
@@ -61,7 +65,6 @@ public class AdapterPropertiesTest {
public void setUp() throws Exception {
mTargetContext = InstrumentationRegistry.getTargetContext();
- MockitoAnnotations.initMocks(this);
doReturn(mNativeInterface).when(mAdapterService).getNative();
mHandlerThread = new HandlerThread("RemoteDevicesTestHandlerThread");
mHandlerThread.start();
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 68ac543169..729ae74b79 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
@@ -31,14 +31,18 @@ import com.android.bluetooth.x.com.android.modules.utils.SynchronousResultReceiv
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.io.FileDescriptor;
public class AdapterServiceBinderTest {
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock private AdapterService mService;
@Mock private AdapterProperties mAdapterProperties;
@@ -47,7 +51,6 @@ public class AdapterServiceBinderTest {
@Before
public void setUp() {
- MockitoAnnotations.initMocks(this);
mService.mAdapterProperties = mAdapterProperties;
doReturn(true).when(mService).isAvailable();
doNothing().when(mService).enforceCallingOrSelfPermission(any(), any());
diff --git a/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceFactoryResetTest.java b/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceFactoryResetTest.java
index 099c29970a..898e6fd791 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceFactoryResetTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceFactoryResetTest.java
@@ -71,10 +71,12 @@ import com.android.internal.app.IBatteryStats;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.util.HashMap;
import java.util.List;
@@ -86,6 +88,8 @@ public class AdapterServiceFactoryResetTest {
private AdapterService mAdapterService;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
private @Mock Context mMockContext;
private @Mock ApplicationInfo mMockApplicationInfo;
private @Mock Resources mMockResources;
@@ -143,7 +147,6 @@ public class AdapterServiceFactoryResetTest {
@Before
public void setUp() throws PackageManager.NameNotFoundException {
Log.e(TAG, "setUp()");
- MockitoAnnotations.initMocks(this);
mLooper = new TestLooper();
Handler handler = new Handler(mLooper.getLooper());
diff --git a/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceRestartTest.java b/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceRestartTest.java
index 12dac99161..93a6688fe4 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceRestartTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceRestartTest.java
@@ -66,10 +66,12 @@ import com.android.internal.app.IBatteryStats;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.util.HashMap;
@@ -80,6 +82,8 @@ public class AdapterServiceRestartTest {
private AdapterService mAdapterService;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
private @Mock Context mMockContext;
private @Mock ApplicationInfo mMockApplicationInfo;
private @Mock Resources mMockResources;
@@ -124,7 +128,6 @@ public class AdapterServiceRestartTest {
@Before
public void setUp() throws PackageManager.NameNotFoundException {
Log.e(TAG, "setUp()");
- MockitoAnnotations.initMocks(this);
mLooper = new TestLooper();
Handler handler = new Handler(mLooper.getLooper());
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 cc84dbc68f..1e1fcc8447 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
@@ -90,7 +90,8 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -115,6 +116,8 @@ public class AdapterServiceTest {
private AdapterService mAdapterService;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
private @Mock Context mMockContext;
private @Mock ApplicationInfo mMockApplicationInfo;
private @Mock Resources mMockResources;
@@ -186,7 +189,6 @@ public class AdapterServiceTest {
@Before
public void setUp() throws PackageManager.NameNotFoundException {
Log.e(TAG, "setUp()");
- MockitoAnnotations.initMocks(this);
mLooper = new TestLooper();
Handler handler = new Handler(mLooper.getLooper());
diff --git a/android/app/tests/unit/src/com/android/bluetooth/btservice/AudioRoutingManagerTest.java b/android/app/tests/unit/src/com/android/bluetooth/btservice/AudioRoutingManagerTest.java
index d294c33e77..f4da3aa7e1 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/btservice/AudioRoutingManagerTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/btservice/AudioRoutingManagerTest.java
@@ -56,12 +56,14 @@ import com.android.bluetooth.le_audio.LeAudioService;
import org.junit.After;
import org.junit.Assume;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.util.ArrayList;
import java.util.Collections;
@@ -91,6 +93,8 @@ public class AudioRoutingManagerTest {
private TestDatabaseManager mDatabaseManager;
private TestLooper mTestLooper;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock private AdapterService mAdapterService;
@Mock private ServiceFactory mServiceFactory;
@Mock private A2dpService mA2dpService;
@@ -102,8 +106,6 @@ public class AudioRoutingManagerTest {
@Before
public void setUp() throws Exception {
- // Set up mocks and test assets
- MockitoAnnotations.initMocks(this);
mTestLooper = new TestLooper();
BluetoothMethodProxy.setInstanceForTesting(mMethodProxy);
doReturn(mTestLooper.getLooper()).when(mMethodProxy).handlerThreadGetLooper(any());
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 91aee3700e..4e571d24e9 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
@@ -40,11 +40,13 @@ import com.android.bluetooth.Utils;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
@MediumTest
@RunWith(AndroidJUnit4.class)
@@ -69,13 +71,14 @@ public class BondStateMachineTest {
private RemoteDevices.DeviceProperties mDeviceProperties;
private int mVerifyCount = 0;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock private AdapterService mAdapterService;
@Mock private AdapterNativeInterface mNativeInterface;
@Before
public void setUp() throws Exception {
mTargetContext = InstrumentationRegistry.getTargetContext();
- MockitoAnnotations.initMocks(this);
TestUtils.setAdapterService(mAdapterService);
doReturn(mNativeInterface).when(mAdapterService).getNative();
mHandlerThread = new HandlerThread("BondStateMachineTestHandlerThread");
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 f2f091fa43..3e9f37b74c 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
@@ -32,10 +32,12 @@ import com.android.bluetooth.TestUtils;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
@MediumTest
@RunWith(AndroidJUnit4.class)
@@ -49,6 +51,8 @@ public class CompanionManagerTest {
private HandlerThread mHandlerThread;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock
private AdapterService mAdapterService;
@Mock
@@ -58,7 +62,6 @@ public class CompanionManagerTest {
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
mTargetContext = InstrumentationRegistry.getTargetContext();
// Prepare the TestUtils
TestUtils.setAdapterService(mAdapterService);
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 ea39f2871d..f1de518872 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
@@ -50,10 +50,12 @@ import com.android.bluetooth.opp.BluetoothShare;
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.util.ArrayList;
import java.util.Arrays;
@@ -73,11 +75,12 @@ public class DataMigrationTest {
private Context mTargetContext;
private SharedPreferences mPrefs;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock private Context mMockContext;
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
mTargetContext = InstrumentationRegistry.getTargetContext();
mTargetContext.deleteSharedPreferences(TEST_PREF);
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 b642319699..273ac96b22 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
@@ -31,10 +31,12 @@ import com.google.common.hash.Funnels;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.io.ByteArrayInputStream;
import java.io.IOException;
@@ -50,6 +52,8 @@ public class MetricsLoggerTest {
private static final String TEST_BLOOMFILTER_NAME = "TestBloomfilter";
private TestableMetricsLogger mTestableMetricsLogger;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock
private AdapterService mMockAdapterService;
@@ -80,7 +84,6 @@ public class MetricsLoggerTest {
@Before
public void setUp() {
- MockitoAnnotations.initMocks(this);
// Dump metrics to clean up internal states
MetricsLogger.dumpProto(BluetoothLog.newBuilder());
mTestableMetricsLogger = new TestableMetricsLogger();
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 f08886106a..f0cf9e32c6 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
@@ -50,7 +50,8 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.util.ArrayList;
import java.util.Collections;
@@ -72,6 +73,8 @@ public class PhonePolicyTest {
private PhonePolicy mPhonePolicy;
private boolean mOriginalDualModeState;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock private AdapterService mAdapterService;
@Mock private ServiceFactory mServiceFactory;
@Mock private HeadsetService mHeadsetService;
@@ -81,7 +84,6 @@ public class PhonePolicyTest {
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
// Stub A2DP and HFP
when(mHeadsetService.connect(any(BluetoothDevice.class))).thenReturn(true);
when(mA2dpService.connect(any(BluetoothDevice.class))).thenReturn(true);
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 660fdb78dc..fb8e0ba914 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
@@ -47,12 +47,14 @@ import com.android.bluetooth.vc.VolumeControlNativeInterface;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
@@ -69,6 +71,8 @@ public class ProfileServiceTest {
private AdapterService mAdapterService =
new AdapterService(InstrumentationRegistry.getTargetContext());
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock private DatabaseManager mDatabaseManager;
private int[] mProfiles;
@@ -132,7 +136,6 @@ public class ProfileServiceTest {
}
Assert.assertNotNull(Looper.myLooper());
- MockitoAnnotations.initMocks(this);
doReturn(mDatabaseManager).when(mAdapterService).getDatabase();
doNothing().when(mAdapterService).addProfile(any());
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 54d3e7bf10..5cbd92d4b3 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
@@ -31,11 +31,13 @@ import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Ignore;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.util.ArrayList;
@@ -54,13 +56,14 @@ public class RemoteDevicesTest {
private Context mTargetContext;
private BluetoothManager mBluetoothManager;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock private AdapterService mAdapterService;
@Before
public void setUp() {
mTargetContext = InstrumentationRegistry.getTargetContext();
- MockitoAnnotations.initMocks(this);
mDevice1 = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(TEST_BT_ADDR_1);
mHandlerThread = new HandlerThread("RemoteDevicesTestHandlerThread");
mHandlerThread.start();
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 23aac3991c..36be66af70 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
@@ -41,11 +41,13 @@ import com.android.bluetooth.hfp.HeadsetService;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
@MediumTest
@RunWith(AndroidJUnit4.class)
@@ -59,6 +61,8 @@ public class SilenceDeviceManagerTest {
private static final String TEST_BT_ADDR = "11:22:33:44:55:66";
private int mVerifyCount = 0;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock private AdapterService mAdapterService;
@Mock private ServiceFactory mServiceFactory;
@Mock private A2dpService mA2dpService;
@@ -69,8 +73,6 @@ public class SilenceDeviceManagerTest {
public void setUp() throws Exception {
mContext = InstrumentationRegistry.getTargetContext();
- // Set up mocks and test assets
- MockitoAnnotations.initMocks(this);
TestUtils.setAdapterService(mAdapterService);
when(mServiceFactory.getA2dpService()).thenReturn(mA2dpService);
when(mServiceFactory.getHeadsetService()).thenReturn(mHeadsetService);
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 1e78e0c86b..ae60fb4d7e 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
@@ -24,11 +24,13 @@ import org.junit.After;
import org.junit.Assert;
import org.junit.Assume;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.io.IOException;
import java.nio.file.Files;
@@ -44,6 +46,8 @@ public final class BluetoothKeystoreServiceTest {
private static final String TAG = "BluetoothKeystoreServiceTest";
private BluetoothKeystoreService mBluetoothKeystoreService;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock private BluetoothKeystoreNativeInterface mMockNativeInterface;
// Please also check bt_stack string configuration if you want to change the content.
@@ -123,7 +127,6 @@ public final class BluetoothKeystoreServiceTest {
@Before
public void setUp() {
- MockitoAnnotations.initMocks(this);
Assume.assumeTrue("Ignore test when the user is not primary.", isPrimaryUser());
mBluetoothKeystoreService = new BluetoothKeystoreService(mMockNativeInterface, true);
Assert.assertNotNull(mBluetoothKeystoreService);
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 679850bed7..94c1993b40 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
@@ -61,7 +61,8 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import org.mockito.stubbing.Answer;
import java.io.IOException;
@@ -74,6 +75,8 @@ import java.util.concurrent.TimeUnit;
@RunWith(AndroidJUnit4.class)
public final class DatabaseManagerTest {
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock private AdapterService mAdapterService;
private MetadataDatabase mDatabase;
@@ -103,7 +106,6 @@ public final class DatabaseManagerTest {
new FrameworkSQLiteOpenHelperFactory());
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
TestUtils.setAdapterService(mAdapterService);
mTestDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(TEST_BT_ADDR);
diff --git a/android/app/tests/unit/src/com/android/bluetooth/content_profiles/ContentProfileErrorReportUtilsTest.java b/android/app/tests/unit/src/com/android/bluetooth/content_profiles/ContentProfileErrorReportUtilsTest.java
index bdfe10d5dc..dc4e6dc5e8 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/content_profiles/ContentProfileErrorReportUtilsTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/content_profiles/ContentProfileErrorReportUtilsTest.java
@@ -22,7 +22,6 @@ import android.os.SystemClock;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
-import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
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 9b9b0b9d4e..460d9df200 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
@@ -29,13 +29,17 @@ import android.os.ParcelUuid;
import com.android.bluetooth.x.com.android.modules.utils.SynchronousResultReceiver;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
public class BluetoothCsisBinderTest {
private static final String TEST_DEVICE_ADDRESS = "00:00:00:00:00:00";
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock
private CsipSetCoordinatorService mService;
@@ -46,7 +50,6 @@ public class BluetoothCsisBinderTest {
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
mBinder = new CsipSetCoordinatorService.BluetoothCsisBinder(mService);
mAttributionSource = new AttributionSource.Builder(1).build();
mTestDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(TEST_DEVICE_ADDRESS);
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 7c3bd07096..d212f044b0 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
@@ -43,11 +43,13 @@ import com.android.bluetooth.le_audio.LeAudioService;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.util.HashMap;
import java.util.List;
@@ -72,6 +74,8 @@ public class CsipSetCoordinatorServiceTest {
private CsipSetCoordinatorStateMachine mCsipSetCoordinatorStateMachine;
private static final int TIMEOUT_MS = 1000;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock private AdapterService mAdapterService;
@Mock private LeAudioService mLeAudioService;
@Spy
@@ -92,8 +96,6 @@ public class CsipSetCoordinatorServiceTest {
}
Assert.assertNotNull(Looper.myLooper());
- // Set up mocks and test assets
- MockitoAnnotations.initMocks(this);
TestUtils.setAdapterService(mAdapterService);
doReturn(mDatabaseManager).when(mAdapterService).getDatabase();
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 0c09204d33..230bf6c33d 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
@@ -33,17 +33,22 @@ import android.content.Intent;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
+
import androidx.test.filters.MediumTest;
import androidx.test.runner.AndroidJUnit4;
+
import com.android.bluetooth.TestUtils;
import com.android.bluetooth.btservice.AdapterService;
+
import org.hamcrest.core.IsInstanceOf;
import org.junit.*;
+import org.junit.Rule;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
@MediumTest
@RunWith(AndroidJUnit4.class)
@@ -56,6 +61,8 @@ public class CsipSetCoordinatorStateMachineTest {
private CsipSetCoordinatorStateMachineWrapper mStateMachine;
private static final int TIMEOUT_MS = 1000;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock private AdapterService mAdapterService;
@Mock private CsipSetCoordinatorService mService;
@Mock private CsipSetCoordinatorNativeInterface mNativeInterface;
@@ -66,8 +73,6 @@ public class CsipSetCoordinatorStateMachineTest {
System.setProperty("dexmaker.share_classloader", "true");
}
- // Set up mocks and test assets
- MockitoAnnotations.initMocks(this);
TestUtils.setAdapterService(mAdapterService);
mAdapter = BluetoothAdapter.getDefaultAdapter();
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 c7bf403325..9c884df9ad 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
@@ -37,10 +37,12 @@ import com.android.bluetooth.btservice.AdapterService;
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
/**
* Test cases for {@link AdvertiseManager}.
@@ -49,6 +51,8 @@ import org.mockito.MockitoAnnotations;
@RunWith(AndroidJUnit4.class)
public class AdvertiseManagerTest {
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock
private AdapterService mAdapterService;
@@ -71,7 +75,6 @@ public class AdvertiseManagerTest {
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
TestUtils.setAdapterService(mAdapterService);
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 6b054f3b7e..66d0750116 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
@@ -34,11 +34,13 @@ import com.android.bluetooth.btservice.MetricsLogger;
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
/**
* Test cases for {@link AppAdvertiseStats}.
@@ -47,6 +49,8 @@ import org.mockito.MockitoAnnotations;
@RunWith(AndroidJUnit4.class)
public class AppAdvertiseStatsTest {
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock
private ContextMap map;
@@ -58,7 +62,6 @@ public class AppAdvertiseStatsTest {
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
MetricsLogger.setInstanceForTesting(mMetricsLogger);
}
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 6d7ba9c22d..d29e96d781 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
@@ -35,6 +35,7 @@ import androidx.test.runner.AndroidJUnit4;
import com.android.bluetooth.BluetoothMethodProxy;
import com.android.bluetooth.TestUtils;
import com.android.bluetooth.btservice.AdapterService;
+import com.android.bluetooth.le_scan.TransitionalScanHelper;
import org.junit.After;
import org.junit.Before;
@@ -42,8 +43,9 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.util.UUID;
@@ -58,9 +60,12 @@ public class ContextMapTest {
@Rule
public final ServiceTestRule mServiceRule = new ServiceTestRule();
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock private AdapterService mAdapterService;
@Mock private AppAdvertiseStats appAdvertiseStats;
@Mock private GattService mMockGatt;
+ @Mock private TransitionalScanHelper mMockScanHelper;
@Mock private PackageManager mMockPackageManager;
@Spy
@@ -68,7 +73,6 @@ public class ContextMapTest {
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
BluetoothMethodProxy.setInstanceForTesting(mMapMethodProxy);
TestUtils.setAdapterService(mAdapterService);
@@ -91,7 +95,7 @@ public class ContextMapTest {
int id = 12345;
contextMap.add(id, null, mMockGatt);
- contextMap.add(UUID.randomUUID(), null, null, null, mMockGatt);
+ contextMap.add(UUID.randomUUID(), null, null, null, mMockGatt, mMockScanHelper);
int appUid = Binder.getCallingUid();
@@ -169,7 +173,7 @@ public class ContextMapTest {
int id = 12345;
contextMap.add(id, null, mMockGatt);
- contextMap.add(UUID.randomUUID(), null, null, null, mMockGatt);
+ contextMap.add(UUID.randomUUID(), null, null, null, mMockGatt, mMockScanHelper);
contextMap.recordAdvertiseStop(id);
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 5d1eea0ade..077d2b9f4b 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
@@ -40,11 +40,13 @@ import com.android.bluetooth.btservice.AdapterService;
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.util.UUID;
@@ -54,6 +56,8 @@ import java.util.UUID;
@SmallTest
@RunWith(AndroidJUnit4.class)
public class DistanceMeasurementManagerTest {
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock private DistanceMeasurementNativeInterface mDistanceMeasurementNativeInterface;
@Mock private AdapterService mAdapterService;
@Mock private IDistanceMeasurementCallback mCallback;
@@ -66,7 +70,6 @@ public class DistanceMeasurementManagerTest {
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
doReturn(IDENTITY_ADDRESS).when(mAdapterService).getIdentityAddress(IDENTITY_ADDRESS);
DistanceMeasurementNativeInterface.setInstance(mDistanceMeasurementNativeInterface);
mDistanceMeasurementManager = new DistanceMeasurementManager(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 d3e562207d..603b20fe45 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
@@ -34,10 +34,12 @@ import androidx.test.runner.AndroidJUnit4;
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.util.UUID;
@@ -47,6 +49,8 @@ import java.util.UUID;
@SmallTest
@RunWith(AndroidJUnit4.class)
public class DistanceMeasurementTrackerTest {
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock private DistanceMeasurementManager mDistanceMeasurementManager;
@Mock private IDistanceMeasurementCallback mCallback;
private DistanceMeasurementTracker mTracker;
@@ -61,7 +65,6 @@ public class DistanceMeasurementTrackerTest {
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
mUuid = UUID.randomUUID();
mDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(IDENTITY_ADDRESS);
mParams = new DistanceMeasurementParams.Builder(mDevice)
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 ab83f1d6e4..8d7f4aafe7 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
@@ -25,11 +25,12 @@ import android.content.Intent;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
-import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
/**
* Test cases for {@link GattDebugUtils}.
@@ -38,14 +39,11 @@ import org.mockito.MockitoAnnotations;
@RunWith(AndroidJUnit4.class)
public class GattDebugUtilsTest {
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock
private GattService mService;
- @Before
- public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
- }
-
@Test
public void handleDebugAction() {
Intent intent = new Intent(GattDebugUtils.ACTION_GATT_TEST_USAGE);
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 1c1fda0007..0bec207562 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
@@ -46,13 +46,16 @@ import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
+import com.android.bluetooth.le_scan.TransitionalScanHelper;
import com.android.bluetooth.x.com.android.modules.utils.SynchronousResultReceiver;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.util.ArrayList;
import java.util.List;
@@ -64,8 +67,11 @@ public class GattServiceBinderTest {
private static final String REMOTE_DEVICE_ADDRESS = "00:00:00:00:00:00";
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock
private GattService mService;
+ @Mock private TransitionalScanHelper mScanHelper;
private Context mContext;
private BluetoothDevice mDevice;
@@ -80,8 +86,8 @@ public class GattServiceBinderTest {
Intent intent = new Intent();
mPendingIntent = PendingIntent.getBroadcast(mContext, 0, intent,
PendingIntent.FLAG_IMMUTABLE);
- MockitoAnnotations.initMocks(this);
when(mService.isAvailable()).thenReturn(true);
+ when(mService.getTransitionalScanHelper()).thenReturn(mScanHelper);
mBinder = new GattService.BluetoothGattBinder(mService);
mAttributionSource = new AttributionSource.Builder(1).build();
mDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(REMOTE_DEVICE_ADDRESS);
@@ -126,7 +132,7 @@ public class GattServiceBinderTest {
mBinder.registerScanner(callback, workSource, mAttributionSource,
SynchronousResultReceiver.get());
- verify(mService).registerScanner(callback, workSource, mAttributionSource);
+ verify(mScanHelper).registerScanner(callback, workSource, mAttributionSource);
}
@Test
@@ -135,7 +141,7 @@ public class GattServiceBinderTest {
mBinder.unregisterScanner(scannerId, mAttributionSource, SynchronousResultReceiver.get());
- verify(mService).unregisterScanner(scannerId, mAttributionSource);
+ verify(mScanHelper).unregisterScanner(scannerId, mAttributionSource);
}
@Test
@@ -147,7 +153,7 @@ public class GattServiceBinderTest {
mBinder.startScan(scannerId, settings, filters, mAttributionSource,
SynchronousResultReceiver.get());
- verify(mService).startScan(scannerId, settings, filters, mAttributionSource);
+ verify(mScanHelper).startScan(scannerId, settings, filters, mAttributionSource);
}
@Test
@@ -158,8 +164,8 @@ public class GattServiceBinderTest {
mBinder.startScanForIntent(mPendingIntent, settings, filters, mAttributionSource,
SynchronousResultReceiver.get());
- verify(mService).registerPiAndStartScan(mPendingIntent, settings, filters,
- mAttributionSource);
+ verify(mScanHelper)
+ .registerPiAndStartScan(mPendingIntent, settings, filters, mAttributionSource);
}
@Test
@@ -167,7 +173,7 @@ public class GattServiceBinderTest {
mBinder.stopScanForIntent(mPendingIntent, mAttributionSource,
SynchronousResultReceiver.get());
- verify(mService).stopScan(mPendingIntent, mAttributionSource);
+ verify(mScanHelper).stopScan(mPendingIntent, mAttributionSource);
}
@Test
@@ -176,7 +182,7 @@ public class GattServiceBinderTest {
mBinder.stopScan(scannerId, mAttributionSource, SynchronousResultReceiver.get());
- verify(mService).stopScan(scannerId, mAttributionSource);
+ verify(mScanHelper).stopScan(scannerId, mAttributionSource);
}
@Test
@@ -186,7 +192,7 @@ public class GattServiceBinderTest {
mBinder.flushPendingBatchResults(scannerId, mAttributionSource,
SynchronousResultReceiver.get());
- verify(mService).flushPendingBatchResults(scannerId, mAttributionSource);
+ verify(mScanHelper).flushPendingBatchResults(scannerId, mAttributionSource);
}
@Test
@@ -710,7 +716,7 @@ public class GattServiceBinderTest {
mBinder.registerSync(scanResult, skip, timeout, callback,
mAttributionSource, SynchronousResultReceiver.get());
- verify(mService).registerSync(scanResult, skip, timeout, callback, mAttributionSource);
+ verify(mScanHelper).registerSync(scanResult, skip, timeout, callback, mAttributionSource);
}
@Test
@@ -721,7 +727,7 @@ public class GattServiceBinderTest {
mBinder.transferSync(mDevice, serviceData, syncHandle,
mAttributionSource, SynchronousResultReceiver.get());
- verify(mService).transferSync(mDevice, serviceData, syncHandle, mAttributionSource);
+ verify(mScanHelper).transferSync(mDevice, serviceData, syncHandle, mAttributionSource);
}
@Test
@@ -733,8 +739,8 @@ public class GattServiceBinderTest {
mBinder.transferSetInfo(mDevice, serviceData, advHandle, callback,
mAttributionSource, SynchronousResultReceiver.get());
- verify(mService).transferSetInfo(mDevice, serviceData, advHandle, callback,
- mAttributionSource);
+ verify(mScanHelper)
+ .transferSetInfo(mDevice, serviceData, advHandle, callback, mAttributionSource);
}
@Test
@@ -743,7 +749,7 @@ public class GattServiceBinderTest {
mBinder.unregisterSync(callback, mAttributionSource, SynchronousResultReceiver.get());
- verify(mService).unregisterSync(callback, mAttributionSource);
+ verify(mScanHelper).unregisterSync(callback, mAttributionSource);
}
@Test
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 9f2390e44c..50083b6d96 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
@@ -33,18 +33,11 @@ import android.bluetooth.le.AdvertisingSetParameters;
import android.bluetooth.le.DistanceMeasurementMethod;
import android.bluetooth.le.DistanceMeasurementParams;
import android.bluetooth.le.IDistanceMeasurementCallback;
-import android.bluetooth.le.IPeriodicAdvertisingCallback;
-import android.bluetooth.le.IScannerCallback;
import android.bluetooth.le.PeriodicAdvertisingParameters;
-import android.bluetooth.le.ScanResult;
-import android.bluetooth.le.ScanSettings;
import android.content.AttributionSource;
import android.content.Context;
import android.content.res.Resources;
import android.location.LocationManager;
-import android.os.Binder;
-import android.os.RemoteException;
-import android.os.WorkSource;
import android.platform.test.flag.junit.SetFlagsRule;
import androidx.test.InstrumentationRegistry;
@@ -55,26 +48,21 @@ import androidx.test.runner.AndroidJUnit4;
import com.android.bluetooth.TestUtils;
import com.android.bluetooth.btservice.AdapterService;
import com.android.bluetooth.btservice.CompanionManager;
-import com.android.bluetooth.le_scan.AppScanStats;
-import com.android.bluetooth.le_scan.PeriodicScanManager;
-import com.android.bluetooth.le_scan.ScanClient;
import com.android.bluetooth.le_scan.ScanManager;
import com.android.bluetooth.le_scan.TransitionalScanHelper;
import com.android.bluetooth.flags.Flags;
import org.junit.After;
-import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.mockito.ArgumentMatcher;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -95,6 +83,8 @@ public class GattServiceTest {
private static final int TIMEOUT_MS = 5_000;
private Context mTargetContext;
private GattService mService;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock private GattService.ClientMap mClientMap;
@Mock private TransitionalScanHelper.ScannerMap mScannerMap;
@@ -102,8 +92,6 @@ public class GattServiceTest {
@Mock
private TransitionalScanHelper.ScannerMap.App mApp;
- @Mock private GattService.PendingIntentInfo mPiInfo;
- @Mock private PeriodicScanManager mPeriodicScanManager;
@Mock private ScanManager mScanManager;
@Mock private Set<String> mReliableQueue;
@Mock private GattService.ServerMap mServerMap;
@@ -128,13 +116,11 @@ public class GattServiceTest {
public void setUp() throws Exception {
mTargetContext = InstrumentationRegistry.getTargetContext();
- MockitoAnnotations.initMocks(this);
TestUtils.setAdapterService(mAdapterService);
GattObjectsFactory.setInstanceForTesting(mFactory);
doReturn(mNativeInterface).when(mFactory).getNativeInterface();
- doReturn(mScanManager).when(mFactory).createScanManager(any(), any(), any(), any());
- doReturn(mPeriodicScanManager).when(mFactory).createPeriodicScanManager(any());
+ doReturn(mScanManager).when(mFactory).createScanManager(any(), any(), any(), any(), any());
doReturn(mDistanceMeasurementManager).when(mFactory)
.createDistanceMeasurementManager(any());
@@ -190,14 +176,6 @@ public class GattServiceTest {
}
@Test
- public void testParseBatchTimestamp() {
- long timestampNanos = mService.parseTimestampNanos(new byte[]{
- -54, 7
- });
- Assert.assertEquals(99700000000L, timestampNanos);
- }
-
- @Test
public void emptyClearServices() {
int serverIf = 1;
@@ -261,81 +239,6 @@ public class GattServiceTest {
}
@Test
- public void continuePiStartScan() {
- int scannerId = 1;
-
- mPiInfo.settings = new ScanSettings.Builder().build();
- mApp.info = mPiInfo;
-
- AppScanStats appScanStats = mock(AppScanStats.class);
- doReturn(appScanStats).when(mScannerMap).getAppScanStatsById(scannerId);
-
- mService.continuePiStartScan(scannerId, mApp);
-
- verify(appScanStats).recordScanStart(
- mPiInfo.settings, mPiInfo.filters, false, false, scannerId);
- verify(mScanManager).startScan(any());
- }
-
- @Test
- public void continuePiStartScanCheckUid() {
- int scannerId = 1;
-
- mPiInfo.settings = new ScanSettings.Builder().build();
- mPiInfo.callingUid = 123;
- mApp.info = mPiInfo;
-
- AppScanStats appScanStats = mock(AppScanStats.class);
- doReturn(appScanStats).when(mScannerMap).getAppScanStatsById(scannerId);
-
- mService.continuePiStartScan(scannerId, mApp);
-
- verify(appScanStats)
- .recordScanStart(mPiInfo.settings, mPiInfo.filters, false, false, scannerId);
- verify(mScanManager)
- .startScan(
- argThat(
- new ArgumentMatcher<ScanClient>() {
- @Override
- public boolean matches(ScanClient client) {
- return mPiInfo.callingUid == client.appUid;
- }
- }));
- }
-
- @Test
- public void onBatchScanReportsInternal_deliverBatchScan() throws RemoteException {
- int status = 1;
- int scannerId = 2;
- int reportType = ScanManager.SCAN_RESULT_TYPE_FULL;
- int numRecords = 1;
- byte[] recordData = new byte[]{0x01, 0x02, 0x03, 0x04, 0x05,
- 0x06, 0x07, 0x08, 0x09, 0x00, 0x00, 0x00, 0x00};
-
- Set<ScanClient> scanClientSet = new HashSet<>();
- ScanClient scanClient = new ScanClient(scannerId);
- scanClient.associatedDevices = new ArrayList<>();
- scanClient.associatedDevices.add("02:00:00:00:00:00");
- scanClient.scannerId = scannerId;
- scanClientSet.add(scanClient);
- doReturn(scanClientSet).when(mScanManager).getFullBatchScanQueue();
- doReturn(mApp).when(mScannerMap).getById(scanClient.scannerId);
-
- mService.onBatchScanReportsInternal(status, scannerId, reportType, numRecords, recordData);
- verify(mScanManager).callbackDone(scannerId, status);
-
- reportType = ScanManager.SCAN_RESULT_TYPE_TRUNCATED;
- recordData = new byte[]{0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
- 0x06, 0x04, 0x02, 0x02, 0x00, 0x00, 0x02};
- doReturn(scanClientSet).when(mScanManager).getBatchScanQueue();
- IScannerCallback callback = mock(IScannerCallback.class);
- mApp.callback = callback;
-
- mService.onBatchScanReportsInternal(status, scannerId, reportType, numRecords, recordData);
- verify(callback).onBatchScanResults(any());
- }
-
- @Test
public void clientConnect() throws Exception {
int clientIf = 1;
String address = REMOTE_DEVICE_ADDRESS;
@@ -367,28 +270,6 @@ public class GattServiceTest {
}
@Test
- public void enforceReportDelayFloor() {
- long reportDelayFloorHigher = GattService.DEFAULT_REPORT_DELAY_FLOOR + 1;
- ScanSettings scanSettings = new ScanSettings.Builder()
- .setReportDelay(reportDelayFloorHigher)
- .build();
-
- ScanSettings newScanSettings = mService.enforceReportDelayFloor(scanSettings);
-
- assertThat(newScanSettings.getReportDelayMillis())
- .isEqualTo(scanSettings.getReportDelayMillis());
-
- ScanSettings scanSettingsFloor = new ScanSettings.Builder()
- .setReportDelay(1)
- .build();
-
- ScanSettings newScanSettingsFloor = mService.enforceReportDelayFloor(scanSettingsFloor);
-
- assertThat(newScanSettingsFloor.getReportDelayMillis())
- .isEqualTo(GattService.DEFAULT_REPORT_DELAY_FLOOR);
- }
-
- @Test
public void setAdvertisingData() {
int advertiserId = 1;
AdvertiseData data = new AdvertiseData.Builder().build();
@@ -481,84 +362,6 @@ public class GattServiceTest {
}
@Test
- public void registerScanner() throws Exception {
- IScannerCallback callback = mock(IScannerCallback.class);
- WorkSource workSource = mock(WorkSource.class);
-
- AppScanStats appScanStats = mock(AppScanStats.class);
- doReturn(appScanStats).when(mScannerMap).getAppScanStatsByUid(Binder.getCallingUid());
-
- mService.registerScanner(callback, workSource, mAttributionSource);
- verify(mScannerMap).add(any(), eq(workSource), eq(callback), eq(null), eq(mService));
- verify(mScanManager).registerScanner(any());
- }
-
- @Test
- public void flushPendingBatchResults() {
- int scannerId = 3;
-
- mService.flushPendingBatchResults(scannerId, mAttributionSource);
- verify(mScanManager).flushBatchScanResults(new ScanClient(scannerId));
- }
-
- @Test
- public void onScanResult_remoteException_clientDied() throws Exception {
- mSetFlagsRule.enableFlags(Flags.FLAG_LE_SCAN_FIX_REMOTE_EXCEPTION);
- int scannerId = 1;
-
- int eventType = 0;
- int addressType = 0;
- String address = "02:00:00:00:00:00";
- int primaryPhy = 0;
- int secondPhy = 0;
- int advertisingSid = 0;
- int txPower = 0;
- int rssi = 0;
- int periodicAdvInt = 0;
- byte[] advData = new byte[0];
-
- ScanClient scanClient = new ScanClient(scannerId);
- scanClient.scannerId = scannerId;
- scanClient.hasNetworkSettingsPermission = true;
- scanClient.settings =
- new ScanSettings.Builder()
- .setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES)
- .setLegacy(false)
- .build();
-
- AppScanStats appScanStats = mock(AppScanStats.class);
- IScannerCallback callback = mock(IScannerCallback.class);
-
- mApp.callback = callback;
- mApp.appScanStats = appScanStats;
- Set<ScanClient> scanClientSet = Collections.singleton(scanClient);
-
- doReturn(address).when(mAdapterService).getIdentityAddress(anyString());
- doReturn(scanClientSet).when(mScanManager).getRegularScanQueue();
- doReturn(mApp).when(mScannerMap).getById(scanClient.scannerId);
- doReturn(appScanStats).when(mScannerMap).getAppScanStatsById(scanClient.scannerId);
-
- // Simulate remote client crash
- doThrow(new RemoteException()).when(callback).onScanResult(any());
-
- mService.onScanResult(
- eventType,
- addressType,
- address,
- primaryPhy,
- secondPhy,
- advertisingSid,
- txPower,
- rssi,
- periodicAdvInt,
- advData,
- address);
-
- assertThat(scanClient.appDied).isTrue();
- verify(appScanStats).recordScanStop(scannerId);
- }
-
- @Test
public void readCharacteristic() {
int clientIf = 1;
String address = REMOTE_DEVICE_ADDRESS;
@@ -789,45 +592,6 @@ public class GattServiceTest {
}
@Test
- public void registerSync() {
- ScanResult scanResult = new ScanResult(mDevice, 1, 2, 3, 4, 5, 6, 7, null, 8);
- int skip = 1;
- int timeout = 2;
- IPeriodicAdvertisingCallback callback = mock(IPeriodicAdvertisingCallback.class);
-
- mService.registerSync(scanResult, skip, timeout, callback, mAttributionSource);
- verify(mPeriodicScanManager).startSync(scanResult, skip, timeout, callback);
- }
-
- @Test
- public void transferSync() {
- int serviceData = 1;
- int syncHandle = 2;
-
- mService.transferSync(mDevice, serviceData, syncHandle, mAttributionSource);
- verify(mPeriodicScanManager).transferSync(mDevice, serviceData, syncHandle);
- }
-
- @Test
- public void transferSetInfo() {
- int serviceData = 1;
- int advHandle = 2;
- IPeriodicAdvertisingCallback callback = mock(IPeriodicAdvertisingCallback.class);
-
- mService.transferSetInfo(mDevice, serviceData, advHandle, callback,
- mAttributionSource);
- verify(mPeriodicScanManager).transferSetInfo(mDevice, serviceData, advHandle, callback);
- }
-
- @Test
- public void unregisterSync() {
- IPeriodicAdvertisingCallback callback = mock(IPeriodicAdvertisingCallback.class);
-
- mService.unregisterSync(callback, mAttributionSource);
- verify(mPeriodicScanManager).stopSync(callback);
- }
-
- @Test
public void unregAll() throws Exception {
int appId = 1;
List<Integer> appIds = new ArrayList<>();
diff --git a/android/app/tests/unit/src/com/android/bluetooth/hap/HapClientNativeInterfaceTest.java b/android/app/tests/unit/src/com/android/bluetooth/hap/HapClientNativeInterfaceTest.java
index 1d4ecbe2e7..1229c97080 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/hap/HapClientNativeInterfaceTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/hap/HapClientNativeInterfaceTest.java
@@ -26,14 +26,18 @@ import android.bluetooth.BluetoothProfile;
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
public class HapClientNativeInterfaceTest {
private static final byte[] TEST_DEVICE_ADDRESS =
new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock
HapClientService mService;
@@ -41,7 +45,6 @@ public class HapClientNativeInterfaceTest {
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
when(mService.isAvailable()).thenReturn(true);
HapClientService.setHapClient(mService);
mNativeInterface = HapClientNativeInterface.getInstance();
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 8e1024dbdb..4c878d896f 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
@@ -31,20 +31,25 @@ import android.bluetooth.BluetoothProfile;
import android.content.Intent;
import android.os.HandlerThread;
import android.os.Message;
+
import androidx.test.filters.MediumTest;
import androidx.test.runner.AndroidJUnit4;
+
import com.android.bluetooth.TestUtils;
import com.android.bluetooth.btservice.AdapterService;
+
import org.hamcrest.core.IsInstanceOf;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
@MediumTest
@RunWith(AndroidJUnit4.class)
@@ -56,6 +61,8 @@ public class HapClientStateMachineTest {
private static final int TIMEOUT_MS = 1000;
boolean mIsAdapterServiceSet;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock
private AdapterService mAdapterService;
@Mock
@@ -65,8 +72,6 @@ public class HapClientStateMachineTest {
@Before
public void setUp() throws Exception {
- // Set up mocks and test assets
- MockitoAnnotations.initMocks(this);
TestUtils.setAdapterService(mAdapterService);
mIsAdapterServiceSet = true;
diff --git a/android/app/tests/unit/src/com/android/bluetooth/hap/HapClientTest.java b/android/app/tests/unit/src/com/android/bluetooth/hap/HapClientTest.java
index 8fc9fbe179..fc24a7ec05 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/hap/HapClientTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/hap/HapClientTest.java
@@ -71,13 +71,15 @@ import com.android.bluetooth.x.com.android.modules.utils.SynchronousResultReceiv
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.InOrder;
import org.mockito.Mock;
import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.time.Duration;
import java.util.ArrayList;
@@ -102,6 +104,8 @@ public class HapClientTest {
private HapClientService.BluetoothHapClientBinder mServiceBinder;
private AttributionSource mAttributionSource;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock private AdapterService mAdapterService;
@Mock private DatabaseManager mDatabaseManager;
@Mock private HapClientNativeInterface mNativeInterface;
@@ -116,8 +120,6 @@ public class HapClientTest {
System.setProperty("dexmaker.share_classloader", "true");
}
- // Set up mocks and test assets
- MockitoAnnotations.initMocks(this);
HapClientStateMachine.sConnectTimeoutMs = TIMEOUT_MS;
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 27e1c152f2..c730910e33 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
@@ -32,14 +32,18 @@ import com.android.bluetooth.Utils;
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
public class HearingAidNativeInterfaceTest {
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock private HearingAidService mService;
private HearingAidNativeInterface mNativeInterface;
@@ -47,7 +51,6 @@ public class HearingAidNativeInterfaceTest {
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
when(mService.isAvailable()).thenReturn(true);
HearingAidService.setHearingAidService(mService);
mNativeInterface = HearingAidNativeInterface.getInstance();
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 f690d6502c..f7580331ab 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
@@ -66,8 +66,9 @@ import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.InOrder;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
import org.mockito.hamcrest.MockitoHamcrest;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.time.Duration;
import java.util.HashMap;
@@ -91,6 +92,8 @@ public class HearingAidServiceTest {
private HearingAidService.BluetoothHearingAidBinder mServiceBinder;
private HashMap<BluetoothDevice, LinkedBlockingQueue<Intent>> mDeviceQueueMap;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock private AdapterService mAdapterService;
@Mock private ActiveDeviceManager mActiveDeviceManager;
@Mock private AudioRoutingManager mAudioRoutingManager;
@@ -103,8 +106,6 @@ public class HearingAidServiceTest {
@Before
public void setUp() throws Exception {
- // Set up mocks and test assets
- MockitoAnnotations.initMocks(this);
mInOrder = inOrder(mContext);
TestUtils.mockGetSystemService(
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 e5ed3151fc..f35f6b3435 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
@@ -37,11 +37,13 @@ import org.hamcrest.core.IsInstanceOf;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
@MediumTest
@RunWith(AndroidJUnit4.class)
@@ -53,6 +55,8 @@ public class HearingAidStateMachineTest {
private BluetoothDevice mTestDevice;
private static final int TIMEOUT_MS = 1000;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock private AdapterService mAdapterService;
@Mock private HearingAidService mHearingAidService;
@Mock private HearingAidNativeInterface mHearingAidNativeInterface;
@@ -60,8 +64,6 @@ public class HearingAidStateMachineTest {
@Before
public void setUp() throws Exception {
mTargetContext = InstrumentationRegistry.getTargetContext();
- // Set up mocks and test assets
- MockitoAnnotations.initMocks(this);
TestUtils.setAdapterService(mAdapterService);
mAdapter = BluetoothAdapter.getDefaultAdapter();
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 131c886c52..1ca0830d79 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
@@ -46,11 +46,13 @@ import com.android.internal.telephony.GsmAlphabet;
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
@RunWith(AndroidJUnit4.class)
public class AtPhonebookTest {
@@ -59,6 +61,8 @@ public class AtPhonebookTest {
private BluetoothAdapter mAdapter;
private BluetoothDevice mTestDevice;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock private AdapterService mAdapterService;
@Mock private HeadsetNativeInterface mNativeInterface;
@@ -69,7 +73,6 @@ public class AtPhonebookTest {
@Before
public void setUp() throws Exception {
mTargetContext = InstrumentationRegistry.getTargetContext();
- MockitoAnnotations.initMocks(this);
TestUtils.setAdapterService(mAdapterService);
BluetoothMethodProxy.setInstanceForTesting(mHfpMethodProxy);
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 61e488ebd8..215991d285 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
@@ -26,13 +26,17 @@ import android.content.AttributionSource;
import com.android.bluetooth.x.com.android.modules.utils.SynchronousResultReceiver;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
public class BluetoothHeadsetBinderTest {
private static final String TEST_DEVICE_ADDRESS = "00:00:00:00:00:00";
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock
private HeadsetService mService;
@@ -43,7 +47,6 @@ public class BluetoothHeadsetBinderTest {
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
mBinder = new HeadsetService.BluetoothHeadsetBinder(mService);
mAttributionSource = new AttributionSource.Builder(1).build();
mTestDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(TEST_DEVICE_ADDRESS);
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 58e3116399..2fb01939b7 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
@@ -39,10 +39,12 @@ import com.android.internal.telephony.ISub;
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.util.HashMap;
@@ -52,6 +54,8 @@ import java.util.HashMap;
@MediumTest
@RunWith(AndroidJUnit4.class)
public class HeadsetPhoneStateTest {
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock private ISub mISub;
@Mock private IBinder mISubBinder;
@Mock private HeadsetService mHeadsetService;
@@ -69,7 +73,6 @@ public class HeadsetPhoneStateTest {
Looper.prepare();
}
IpcDataCache.disableForTestMode();
- MockitoAnnotations.initMocks(this);
SubscriptionManager.disableCaching();
TelephonyManager.disableServiceHandleCaching();
// Mock SubscriptionManager.getDefaultSubscriptionId() to return a valid value
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 94af16dc78..5c097e9756 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
@@ -69,8 +69,9 @@ import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.InOrder;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.lang.reflect.Method;
import java.util.Collections;
@@ -110,6 +111,8 @@ public class HeadsetServiceAndStateMachineTest {
boolean mIsAdapterServiceSet;
boolean mIsHeadsetServiceStarted;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock private HeadsetNativeInterface mNativeInterface;
private class HeadsetIntentReceiver extends BroadcastReceiver {
@@ -165,7 +168,6 @@ public class HeadsetServiceAndStateMachineTest {
@Before
public void setUp() throws Exception {
mTargetContext = InstrumentationRegistry.getTargetContext();
- MockitoAnnotations.initMocks(this);
PowerManager powerManager = mTargetContext.getSystemService(PowerManager.class);
mVoiceRecognitionWakeLock =
powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "VoiceRecognitionTest");
@@ -1260,6 +1262,46 @@ public class HeadsetServiceAndStateMachineTest {
verify(mNativeInterface, times(0)).connectAudio(device);
}
+ /**
+ * Test to verify the following behavior regarding phoneStateChanged when the SCO is managed by
+ * the Audio: When phoneStateChange returns, HeadsetStateMachine completes processing
+ * mActiveDevice's CALL_STATE_CHANGED message
+ */
+ @Test
+ public void testPhoneStateChange_SynchronousCallStateChanged() {
+ mSetFlagsRule.enableFlags(Flags.FLAG_IS_SCO_MANAGED_BY_AUDIO);
+
+ BluetoothDevice device = TestUtils.getTestDevice(mAdapter, 0);
+ Assert.assertNotNull(device);
+ connectTestDevice(device);
+
+ BluetoothDevice device2 = TestUtils.getTestDevice(mAdapter, 1);
+ Assert.assertNotNull(device2);
+ connectTestDevice(device2);
+
+ BluetoothDevice device3 = TestUtils.getTestDevice(mAdapter, 2);
+ Assert.assertNotNull(device3);
+ connectTestDevice(device3);
+
+ mHeadsetService.setActiveDevice(device);
+ Assert.assertTrue(mHeadsetService.setActiveDevice(device));
+
+ HeadsetCallState headsetCallState =
+ new HeadsetCallState(
+ 0, 0, HeadsetHalConstants.CALL_STATE_INCOMING, TEST_PHONE_NUMBER, 128, "");
+ mHeadsetService.phoneStateChanged(
+ headsetCallState.mNumActive,
+ headsetCallState.mNumHeld,
+ headsetCallState.mCallState,
+ headsetCallState.mNumber,
+ headsetCallState.mType,
+ headsetCallState.mName,
+ false);
+ // verify phoneStateChanged runs synchronously, which means when phoneStateChange returns,
+ // HeadsetStateMachine completes processing CALL_STATE_CHANGED message
+ verify(mNativeInterface, times(1)).phoneStateChange(device, headsetCallState);
+ }
+
private void connectTestDevice(BluetoothDevice device) {
when(mDatabaseManager.getProfileConnectionPolicy(device, BluetoothProfile.HEADSET))
.thenReturn(BluetoothProfile.CONNECTION_POLICY_UNKNOWN);
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 2aa1e1ff0d..95d70a9aa2 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
@@ -59,11 +59,13 @@ import org.hamcrest.Matchers;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.lang.reflect.Method;
import java.util.ArrayList;
@@ -89,6 +91,8 @@ public class HeadsetServiceTest {
private final HashMap<BluetoothDevice, HeadsetStateMachine> mStateMachines = new HashMap<>();
@Spy private HeadsetObjectsFactory mObjectsFactory = HeadsetObjectsFactory.getInstance();
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock private AdapterService mAdapterService;
@Mock private ActiveDeviceManager mActiveDeviceManager;
@Mock private SilenceDeviceManager mSilenceDeviceManager;
@@ -102,7 +106,6 @@ public class HeadsetServiceTest {
@Before
public void setUp() throws Exception {
mTargetContext = InstrumentationRegistry.getTargetContext();
- MockitoAnnotations.initMocks(this);
TestUtils.setAdapterService(mAdapterService);
// We cannot mock HeadsetObjectsFactory.getInstance() with Mockito.
// Hence we need to use reflection to call a private method to
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 74372219df..c5fcd84cf4 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
@@ -71,7 +71,8 @@ import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.util.ArrayList;
@@ -96,6 +97,8 @@ public class HeadsetStateMachineTest {
private BluetoothDevice mTestDevice;
private ArgumentCaptor<Intent> mIntentArgument = ArgumentCaptor.forClass(Intent.class);
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock private AdapterService mAdapterService;
@Mock private ActiveDeviceManager mActiveDeviceManager;
@Mock private SilenceDeviceManager mSilenceDeviceManager;
@@ -113,7 +116,6 @@ public class HeadsetStateMachineTest {
public void setUp() throws Exception {
mTargetContext = InstrumentationRegistry.getTargetContext();
// Setup mocks and test assets
- MockitoAnnotations.initMocks(this);
TestUtils.setAdapterService(mAdapterService);
// Stub system interface
doReturn(mPhoneState).when(mSystemInterface).getHeadsetPhoneState();
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 9f686827ca..5fee0b31c9 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
@@ -28,16 +28,20 @@ import androidx.test.runner.AndroidJUnit4;
import com.android.bluetooth.x.com.android.modules.utils.SynchronousResultReceiver;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
@SmallTest
@RunWith(AndroidJUnit4.class)
public class HeadsetClientServiceBinderTest {
private static final String REMOTE_DEVICE_ADDRESS = "00:00:00:00:00:00";
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock
private HeadsetClientService mService;
@@ -47,7 +51,6 @@ public class HeadsetClientServiceBinderTest {
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
mRemoteDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(REMOTE_DEVICE_ADDRESS);
mBinder = new HeadsetClientService.BluetoothHeadsetClientBinder(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 a6288f647f..fc08492d05 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
@@ -47,11 +47,13 @@ import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Ignore;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
@MediumTest
@RunWith(AndroidJUnit4.class)
@@ -64,6 +66,8 @@ public class HeadsetClientServiceTest {
private static final int STANDARD_WAIT_MILLIS = 1000;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock private AdapterService mAdapterService;
@Mock private HeadsetClientStateMachine mStateMachine;
@Mock private NativeInterface mNativeInterface;
@@ -73,7 +77,6 @@ public class HeadsetClientServiceTest {
@Before
public void setUp() throws Exception {
mTargetContext = InstrumentationRegistry.getTargetContext();
- MockitoAnnotations.initMocks(this);
TestUtils.setAdapterService(mAdapterService);
mIsAdapterServiceSet = true;
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 f95bd870e6..1228ba1be5 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
@@ -68,13 +68,15 @@ import org.hamcrest.core.IsInstanceOf;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
import org.mockito.hamcrest.MockitoHamcrest;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.util.List;
import java.util.Set;
@@ -91,6 +93,8 @@ public class HeadsetClientStateMachineTest {
private BluetoothDevice mTestDevice;
private Context mTargetContext;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock private AdapterService mAdapterService;
@Mock private Resources mMockHfpResources;
@Mock private HeadsetService mHeadsetService;
@@ -110,7 +114,6 @@ public class HeadsetClientStateMachineTest {
public void setUp() throws Exception {
mTargetContext = InstrumentationRegistry.getTargetContext();
// Setup mocks and test assets
- MockitoAnnotations.initMocks(this);
// Set a valid volume
when(mAudioManager.getStreamVolume(anyInt())).thenReturn(2);
when(mAudioManager.getStreamMaxVolume(anyInt())).thenReturn(10);
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 1db59c0774..5dc40be314 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
@@ -27,14 +27,18 @@ import com.android.bluetooth.btservice.AdapterService;
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+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();
+
@Mock
HeadsetClientService mService;
@Mock
@@ -44,7 +48,6 @@ public class HfpNativeInterfaceTest {
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
when(mService.isAvailable()).thenReturn(true);
HeadsetClientService.setHeadsetClientService(mService);
TestUtils.setAdapterService(mAdapterService);
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 3876a4aa27..48428b7044 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
@@ -32,10 +32,12 @@ import com.android.bluetooth.btservice.AdapterService;
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
@SmallTest
@RunWith(AndroidJUnit4.class)
@@ -44,6 +46,8 @@ public class VendorCommandResponseProcessorTest {
private BluetoothAdapter mAdapter;
private BluetoothDevice mTestDevice;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock private NativeInterface mNativeInterface;
private VendorCommandResponseProcessor mProcessor;
@@ -54,7 +58,6 @@ public class VendorCommandResponseProcessorTest {
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
TestUtils.setAdapterService(mAdapterService);
mAdapter = BluetoothAdapter.getDefaultAdapter();
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 c35ed99425..68918e5965 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
@@ -31,10 +31,12 @@ import androidx.test.runner.AndroidJUnit4;
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.util.List;
import java.util.Set;
@@ -58,12 +60,13 @@ public class HeadsetClientServiceInterfaceTest {
TEST_BUNDLE.putInt("test_int", 0);
}
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock private HeadsetClientService mMockHeadsetClientService;
private HeadsetClientServiceInterface mServiceInterface;
@Before
public void setUp() {
- MockitoAnnotations.initMocks(this);
HeadsetClientService.setHeadsetClientService(mMockHeadsetClientService);
mServiceInterface = new HeadsetClientServiceInterface();
}
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 4be3028948..a4258951d6 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
@@ -49,10 +49,12 @@ import com.android.bluetooth.btservice.AdapterService;
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.util.Arrays;
import java.util.List;
@@ -67,6 +69,8 @@ public class HfpClientConnectionServiceTest {
.getAdapter().getRemoteDevice(TEST_DEVICE_ADDRESS);
private static final String TEST_NUMBER = "000-111-2222";
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock private AdapterService mAdapterService;
@Mock private HeadsetClientService mMockHeadsetClientService;
@Mock private TelecomManager mMockTelecomManager;
@@ -77,7 +81,6 @@ public class HfpClientConnectionServiceTest {
@Before
public void setUp() {
- MockitoAnnotations.initMocks(this);
Context targetContext = InstrumentationRegistry.getTargetContext();
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 f9839328f5..c30e2b86a3 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
@@ -33,11 +33,13 @@ import androidx.test.runner.AndroidJUnit4;
import org.junit.Before;
import org.junit.Ignore;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
@MediumTest
@RunWith(AndroidJUnit4.class)
@@ -47,6 +49,8 @@ public class HfpClientDeviceBlockTest {
private static final String KEY_SCO_STATE = "com.android.bluetooth.hfpclient.SCO_STATE";
private static final String TEST_PACKAGE = "test";
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock
private HeadsetClientService mHeadsetClientService;
@Mock
@@ -65,7 +69,6 @@ public class HfpClientDeviceBlockTest {
@Before
public void setUp() {
- MockitoAnnotations.initMocks(this);
// HfpClientConnectionService.createAccount is static and can't be mocked, so the
// application context and resources must be mocked to avoid NPE when creating an
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 2138729b74..6c6b311240 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
@@ -34,14 +34,18 @@ import android.content.AttributionSource;
import com.android.bluetooth.x.com.android.modules.utils.SynchronousResultReceiver;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
public class BluetoothHidDeviceBinderTest {
private static final String TEST_DEVICE_ADDRESS = "00:00:00:00:00:00";
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock
private HidDeviceService mService;
private AttributionSource mAttributionSource;
@@ -50,7 +54,6 @@ public class BluetoothHidDeviceBinderTest {
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
when(mService.isAvailable()).thenReturn(true);
mBinder = new HidDeviceService.BluetoothHidDeviceBinder(mService);
mAttributionSource = new AttributionSource.Builder(1).build();
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 fd70351493..41b4006ee8 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
@@ -29,13 +29,17 @@ import com.android.bluetooth.btservice.AdapterService;
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+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();
+
@Mock
HidDeviceService mService;
@Mock
@@ -45,7 +49,6 @@ public class HidDeviceNativeInterfaceTest {
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
when(mService.isAvailable()).thenReturn(true);
HidDeviceService.setHidDeviceService(mService);
TestUtils.setAdapterService(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 db4a62ee35..4b6672ec6c 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
@@ -41,10 +41,12 @@ import com.android.bluetooth.btservice.storage.DatabaseManager;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
@@ -70,6 +72,8 @@ public class HidDeviceTest {
private static final int CALLBACK_ON_INTR_DATA = 5;
private static final int CALLBACK_ON_VIRTUAL_UNPLUG = 6;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock private AdapterService mAdapterService;
@Mock private DatabaseManager mDatabaseManager;
@Mock private HidDeviceNativeInterface mHidDeviceNativeInterface;
@@ -100,8 +104,6 @@ public class HidDeviceTest {
}
Assert.assertNotNull(Looper.myLooper());
- // Set up mocks and test assets
- MockitoAnnotations.initMocks(this);
TestUtils.setAdapterService(mAdapterService);
doReturn(mDatabaseManager).when(mAdapterService).getDatabase();
setHidDeviceNativeInterfaceInstance(mHidDeviceNativeInterface);
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 8bedfb3e2a..aeabb31e42 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
@@ -30,7 +30,8 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
@SmallTest
@RunWith(AndroidJUnit4.class)
@@ -38,6 +39,8 @@ public class HidHostServiceBinderTest {
@Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
private static final String REMOTE_DEVICE_ADDRESS = "00:00:00:00:00:00";
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock
private HidHostService mService;
@@ -47,7 +50,6 @@ public class HidHostServiceBinderTest {
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
mRemoteDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(REMOTE_DEVICE_ADDRESS);
mBinder = new HidHostService.BluetoothHidHostBinder(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 41652ab673..e21145d79d 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
@@ -33,10 +33,12 @@ import com.android.bluetooth.btservice.storage.DatabaseManager;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
@MediumTest
@RunWith(AndroidJUnit4.class)
@@ -46,6 +48,8 @@ public class HidHostServiceTest {
private BluetoothDevice mTestDevice;
private Context mTargetContext;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock private AdapterService mAdapterService;
@Mock private DatabaseManager mDatabaseManager;
@Mock private HidHostNativeInterface mNativeInterface;
@@ -53,7 +57,6 @@ public class HidHostServiceTest {
@Before
public void setUp() throws Exception {
mTargetContext = InstrumentationRegistry.getTargetContext();
- MockitoAnnotations.initMocks(this);
TestUtils.setAdapterService(mAdapterService);
when(mAdapterService.getDatabase()).thenReturn(mDatabaseManager);
HidHostNativeInterface.setInstance(mNativeInterface);
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 9e8ebe5d36..6a3443387d 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
@@ -30,10 +30,12 @@ import com.android.bluetooth.btservice.ServiceFactory;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.util.Map;
import java.util.UUID;
@@ -41,6 +43,8 @@ import java.util.UUID;
@MediumTest
@RunWith(AndroidJUnit4.class)
public class ContentControlIdKeeperTest {
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock
ServiceFactory mServiceFactoryMock;
@Mock
@@ -48,7 +52,6 @@ public class ContentControlIdKeeperTest {
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
doReturn(mLeAudioServiceMock).when(mServiceFactoryMock).getLeAudioService();
ContentControlIdKeeper.initForTesting(mServiceFactoryMock);
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 d7f7d419d3..df2877473f 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
@@ -52,7 +52,8 @@ import org.junit.Rule;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.util.List;
import java.util.UUID;
@@ -62,6 +63,8 @@ public class LeAudioBinderTest {
@Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
private LeAudioService mLeAudioService;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock private AdapterService mAdapterService;
@Mock private LeAudioNativeInterface mNativeInterface;
@Mock private DatabaseManager mDatabaseManager;
@@ -79,7 +82,6 @@ public class LeAudioBinderTest {
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
TestUtils.setAdapterService(mAdapterService);
doReturn(false).when(mAdapterService).isQuietModeEnabled();
doReturn(mDatabaseManager).when(mAdapterService).getDatabase();
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 17057c9f3e..8a6a4de6c5 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
@@ -54,8 +54,9 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;
@@ -76,6 +77,8 @@ public class LeAudioBroadcastServiceTest {
private LeAudioService mService;
private LeAudioIntentReceiver mLeAudioIntentReceiver;
private LinkedBlockingQueue<Intent> mIntentQueue;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock private ActiveDeviceManager mActiveDeviceManager;
@Mock
private AdapterService mAdapterService;
@@ -195,8 +198,6 @@ public class LeAudioBroadcastServiceTest {
public void setUp() throws Exception {
mTargetContext = InstrumentationRegistry.getTargetContext();
- // Set up mocks and test assets
- MockitoAnnotations.initMocks(this);
// Use spied objects factory
doNothing().when(mTmapGattServer).start(anyInt());
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 5e4e44a9e6..045b5a2667 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
@@ -27,14 +27,18 @@ import androidx.test.runner.AndroidJUnit4;
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
@RunWith(AndroidJUnit4.class)
public class LeAudioBroadcasterNativeInterfaceTest {
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock
private LeAudioService mMockService;
@@ -42,7 +46,6 @@ public class LeAudioBroadcasterNativeInterfaceTest {
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
when(mMockService.isAvailable()).thenReturn(true);
LeAudioService.setLeAudioService(mMockService);
mNativeInterface = LeAudioBroadcasterNativeInterface.getInstance();
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 7b45a9fa64..cf88ce4925 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
@@ -28,14 +28,18 @@ import androidx.test.runner.AndroidJUnit4;
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
@RunWith(AndroidJUnit4.class)
public class LeAudioNativeInterfaceTest {
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock
private LeAudioService mMockService;
@@ -43,7 +47,6 @@ public class LeAudioNativeInterfaceTest {
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
when(mMockService.isAvailable()).thenReturn(true);
LeAudioService.setLeAudioService(mMockService);
mNativeInterface = LeAudioNativeInterface.getInstance();
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 30bb834a44..9ae849428d 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
@@ -78,8 +78,9 @@ import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.util.HashMap;
import java.util.HashSet;
@@ -118,6 +119,8 @@ public class LeAudioServiceTest {
private BroadcastReceiver mLeAudioIntentReceiver;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock private AdapterService mAdapterService;
@Mock private ActiveDeviceManager mActiveDeviceManager;
@Mock private AudioManager mAudioManager;
@@ -166,8 +169,6 @@ public class LeAudioServiceTest {
public void setUp() throws Exception {
mTargetContext = InstrumentationRegistry.getTargetContext();
- // Set up mocks and test assets
- MockitoAnnotations.initMocks(this);
// Use spied objects factory
doNothing().when(mTmapGattServer).start(anyInt());
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 d372c172fd..2921483669 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
@@ -45,10 +45,12 @@ import com.android.bluetooth.btservice.AdapterService;
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
@MediumTest
@RunWith(AndroidJUnit4.class)
@@ -60,6 +62,8 @@ public class LeAudioStateMachineTest {
private BluetoothDevice mTestDevice;
private static final int TIMEOUT_MS = 1000;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock private AdapterService mAdapterService;
@Mock private LeAudioService mLeAudioService;
@Mock private LeAudioNativeInterface mLeAudioNativeInterface;
@@ -67,8 +71,6 @@ public class LeAudioStateMachineTest {
@Before
public void setUp() throws Exception {
mTargetContext = InstrumentationRegistry.getTargetContext();
- // Set up mocks and test assets
- MockitoAnnotations.initMocks(this);
TestUtils.setAdapterService(mAdapterService);
mAdapter = BluetoothAdapter.getDefaultAdapter();
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 da9e348712..6afe455ca1 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
@@ -37,11 +37,13 @@ import androidx.test.runner.AndroidJUnit4;
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
@MediumTest
@RunWith(AndroidJUnit4.class)
@@ -49,6 +51,8 @@ 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();
+
@Mock
private LeAudioTmapGattServer.BluetoothGattServerProxy mGattServerProxy;
@@ -56,7 +60,6 @@ public class LeAudioTmapGattServerTest {
@Before
public void setUp() {
- MockitoAnnotations.initMocks(this);
doReturn(true).when(mGattServerProxy).open(any());
doReturn(true).when(mGattServerProxy).addService(any());
mServer = new LeAudioTmapGattServer(mGattServerProxy);
diff --git a/android/app/tests/unit/src/com/android/bluetooth/gatt/AdvtFilterOnFoundOnLostInfoTest.java b/android/app/tests/unit/src/com/android/bluetooth/le_scan/AdvtFilterOnFoundOnLostInfoTest.java
index 3eade702b5..674278dee7 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/gatt/AdvtFilterOnFoundOnLostInfoTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/le_scan/AdvtFilterOnFoundOnLostInfoTest.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.bluetooth.gatt;
+package com.android.bluetooth.le_scan;
import static com.google.common.truth.Truth.assertThat;
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 4f0b434cac..d7b92e0ec6 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
@@ -33,7 +33,6 @@ import androidx.test.runner.AndroidJUnit4;
import com.android.bluetooth.TestUtils;
import com.android.bluetooth.btservice.AdapterService;
import com.android.bluetooth.gatt.ContextMap;
-import com.android.bluetooth.gatt.GattService;
import com.android.internal.app.IBatteryStats;
import org.junit.After;
@@ -42,7 +41,8 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.util.ArrayList;
import java.util.List;
@@ -57,10 +57,13 @@ public class AppScanStatsTest {
@Rule
public final ServiceTestRule mServiceRule = new ServiceTestRule();
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock
private ContextMap map;
- @Mock private GattService mMockGatt;
+ @Mock private Context mMockContext;
+ @Mock private TransitionalScanHelper mMockScanHelper;
@Mock private AdapterService mAdapterService;
// BatteryStatsManager is final and cannot be mocked with regular mockito, so just mock the
@@ -70,12 +73,11 @@ public class AppScanStatsTest {
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
TestUtils.setAdapterService(mAdapterService);
TestUtils.mockGetSystemService(
- mMockGatt,
+ mMockContext,
Context.BATTERY_STATS_SERVICE,
BatteryStatsManager.class,
mBatteryStatsManager);
@@ -91,10 +93,11 @@ public class AppScanStatsTest {
String name = "appName";
WorkSource source = null;
- AppScanStats appScanStats = new AppScanStats(name, source, map, mMockGatt);
+ AppScanStats appScanStats =
+ new AppScanStats(name, source, map, mMockContext, mMockScanHelper);
assertThat(appScanStats.mContextMap).isEqualTo(map);
- assertThat(appScanStats.mGattService).isEqualTo(mMockGatt);
+ assertThat(appScanStats.mScanHelper).isEqualTo(mMockScanHelper);
assertThat(appScanStats.isScanning()).isEqualTo(false);
}
@@ -104,7 +107,8 @@ public class AppScanStatsTest {
String name = "appName";
WorkSource source = null;
- AppScanStats appScanStats = new AppScanStats(name, source, map, mMockGatt);
+ AppScanStats appScanStats =
+ new AppScanStats(name, source, map, mMockContext, mMockScanHelper);
ScanSettings settings = new ScanSettings.Builder().build();
List<ScanFilter> filters = new ArrayList<>();
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 61517270c3..1137a51dc8 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
@@ -42,16 +42,20 @@ import com.android.bluetooth.btservice.AdapterService;
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+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();
+
@Mock private PeriodicScanNativeInterface mPeriodicScanNativeInterface;
@Mock private AdapterService mAdapterService;
@Mock private IPeriodicAdvertisingCallback mCallback;
@@ -68,7 +72,6 @@ public class PeriodicScanManagerTest {
@Before
public void setUp() throws Exception {
mTargetContext = InstrumentationRegistry.getTargetContext();
- MockitoAnnotations.initMocks(this);
PeriodicScanNativeInterface.setInstance(mPeriodicScanNativeInterface);
mPeriodicScanManager = new PeriodicScanManager(mAdapterService);
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 97dfb0326f..b1804031b9 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
@@ -85,8 +85,9 @@ import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.util.ArrayList;
import java.util.List;
@@ -125,8 +126,11 @@ public class ScanManagerTest {
@Rule public final ServiceTestRule mServiceRule = new ServiceTestRule();
@Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock private AdapterService mAdapterService;
@Mock private GattService mMockGattService;
+ @Mock private TransitionalScanHelper mMockScanHelper;
@Mock private BluetoothAdapterProxy mBluetoothAdapterProxy;
@Mock private LocationManager mLocationManager;
@Spy private GattObjectsFactory mFactory = GattObjectsFactory.getInstance();
@@ -141,7 +145,6 @@ public class ScanManagerTest {
@Before
public void setUp() throws Exception {
mTargetContext = InstrumentationRegistry.getTargetContext();
- MockitoAnnotations.initMocks(this);
TestUtils.setAdapterService(mAdapterService);
when(mAdapterService.getScanTimeoutMillis())
@@ -197,6 +200,7 @@ public class ScanManagerTest {
mScanManager =
new ScanManager(
mMockGattService,
+ mMockScanHelper,
mAdapterService,
mBluetoothAdapterProxy,
mTestLooper.getLooper());
@@ -208,7 +212,8 @@ public class ScanManagerTest {
assertThat(mLatch).isNotNull();
mScanReportDelay = DEFAULT_SCAN_REPORT_DELAY_MS;
- mMockAppScanStats = spy(new AppScanStats("Test", null, null, mMockGattService));
+ mMockAppScanStats =
+ spy(new AppScanStats("Test", null, null, mMockGattService, mMockScanHelper));
}
@After
diff --git a/android/app/tests/unit/src/com/android/bluetooth/le_scan/TransitionalScanHelperTest.java b/android/app/tests/unit/src/com/android/bluetooth/le_scan/TransitionalScanHelperTest.java
new file mode 100644
index 0000000000..45aff753b0
--- /dev/null
+++ b/android/app/tests/unit/src/com/android/bluetooth/le_scan/TransitionalScanHelperTest.java
@@ -0,0 +1,400 @@
+/*
+ * Copyright 2023 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.
+ */
+
+package com.android.bluetooth.le_scan;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyString;
+import static org.mockito.Mockito.argThat;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothProfile;
+import android.bluetooth.le.IPeriodicAdvertisingCallback;
+import android.bluetooth.le.IScannerCallback;
+import android.bluetooth.le.ScanResult;
+import android.bluetooth.le.ScanSettings;
+import android.content.AttributionSource;
+import android.content.Context;
+import android.content.res.Resources;
+import android.location.LocationManager;
+import android.os.Binder;
+import android.os.RemoteException;
+import android.os.WorkSource;
+import android.os.test.TestLooper;
+import android.platform.test.flag.junit.SetFlagsRule;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.SmallTest;
+import androidx.test.rule.ServiceTestRule;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.bluetooth.TestUtils;
+import com.android.bluetooth.btservice.AdapterService;
+import com.android.bluetooth.btservice.CompanionManager;
+import com.android.bluetooth.gatt.GattObjectsFactory;
+import com.android.bluetooth.gatt.GattNativeInterface;
+
+import com.android.bluetooth.flags.Flags;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentMatcher;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+/** Test cases for {@link TransitionalScanHelper}. */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class TransitionalScanHelperTest {
+
+ private static final String REMOTE_DEVICE_ADDRESS = "00:00:00:00:00:00";
+
+ private TransitionalScanHelper mScanHelper;
+ @Mock private TransitionalScanHelper.ScannerMap mScannerMap;
+
+ @SuppressWarnings("NonCanonicalType")
+ @Mock
+ private TransitionalScanHelper.ScannerMap.App mApp;
+
+ @Mock private TransitionalScanHelper.PendingIntentInfo mPiInfo;
+ @Mock private PeriodicScanManager mPeriodicScanManager;
+ @Mock private ScanManager mScanManager;
+
+ @Rule public final ServiceTestRule mServiceRule = new ServiceTestRule();
+ @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+
+ private BluetoothDevice mDevice;
+ private BluetoothAdapter mAdapter;
+ private AttributionSource mAttributionSource;
+
+ @Mock private Resources mResources;
+ @Mock private AdapterService mAdapterService;
+ @Mock private GattObjectsFactory mFactory;
+ @Mock private GattNativeInterface mNativeInterface;
+ private CompanionManager mBtCompanionManager;
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ TestUtils.setAdapterService(mAdapterService);
+
+ GattObjectsFactory.setInstanceForTesting(mFactory);
+ doReturn(mNativeInterface).when(mFactory).getNativeInterface();
+ doReturn(mScanManager).when(mFactory).createScanManager(any(), any(), any(), any(), any());
+ doReturn(mPeriodicScanManager).when(mFactory).createPeriodicScanManager(any());
+
+ mAdapter = BluetoothAdapter.getDefaultAdapter();
+ mAttributionSource = mAdapter.getAttributionSource();
+ mDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(REMOTE_DEVICE_ADDRESS);
+
+ when(mAdapterService.getResources()).thenReturn(mResources);
+ when(mResources.getInteger(anyInt())).thenReturn(0);
+ when(mAdapterService.getSharedPreferences(anyString(), anyInt()))
+ .thenReturn(
+ InstrumentationRegistry.getTargetContext()
+ .getSharedPreferences(
+ "GattServiceTestPrefs", Context.MODE_PRIVATE));
+
+ TestUtils.mockGetSystemService(
+ mAdapterService, Context.LOCATION_SERVICE, LocationManager.class);
+
+ mBtCompanionManager = new CompanionManager(mAdapterService, null);
+ doReturn(mBtCompanionManager).when(mAdapterService).getCompanionManager();
+
+ TestLooper testLooper = new TestLooper();
+ testLooper.startAutoDispatch();
+
+ mScanHelper =
+ new TransitionalScanHelper(InstrumentationRegistry.getTargetContext(), () -> false);
+ mScanHelper.start(testLooper.getLooper());
+
+ mScanHelper.setScannerMap(mScannerMap);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ mScanHelper.stop();
+ mScanHelper = null;
+
+ TestUtils.clearAdapterService(mAdapterService);
+ GattObjectsFactory.setInstanceForTesting(null);
+ }
+
+ @Test
+ public void testParseBatchTimestamp() {
+ long timestampNanos = mScanHelper.parseTimestampNanos(new byte[] {-54, 7});
+ assertThat(timestampNanos).isEqualTo(99700000000L);
+ }
+
+ @Test
+ public void continuePiStartScan() {
+ int scannerId = 1;
+
+ mPiInfo.settings = new ScanSettings.Builder().build();
+ mApp.info = mPiInfo;
+
+ AppScanStats appScanStats = mock(AppScanStats.class);
+ doReturn(appScanStats).when(mScannerMap).getAppScanStatsById(scannerId);
+
+ mScanHelper.continuePiStartScan(scannerId, mApp);
+
+ verify(appScanStats)
+ .recordScanStart(mPiInfo.settings, mPiInfo.filters, false, false, scannerId);
+ verify(mScanManager).startScan(any());
+ }
+
+ @Test
+ public void continuePiStartScanCheckUid() {
+ int scannerId = 1;
+
+ mPiInfo.settings = new ScanSettings.Builder().build();
+ mPiInfo.callingUid = 123;
+ mApp.info = mPiInfo;
+
+ AppScanStats appScanStats = mock(AppScanStats.class);
+ doReturn(appScanStats).when(mScannerMap).getAppScanStatsById(scannerId);
+
+ mScanHelper.continuePiStartScan(scannerId, mApp);
+
+ verify(appScanStats)
+ .recordScanStart(mPiInfo.settings, mPiInfo.filters, false, false, scannerId);
+ verify(mScanManager)
+ .startScan(
+ argThat(
+ new ArgumentMatcher<ScanClient>() {
+ @Override
+ public boolean matches(ScanClient client) {
+ return mPiInfo.callingUid == client.appUid;
+ }
+ }));
+ }
+
+ @Test
+ public void onBatchScanReportsInternal_deliverBatchScan() throws RemoteException {
+ int status = 1;
+ int scannerId = 2;
+ int reportType = ScanManager.SCAN_RESULT_TYPE_FULL;
+ int numRecords = 1;
+ byte[] recordData =
+ new byte[] {
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x00, 0x00, 0x00, 0x00
+ };
+
+ Set<ScanClient> scanClientSet = new HashSet<>();
+ ScanClient scanClient = new ScanClient(scannerId);
+ scanClient.associatedDevices = new ArrayList<>();
+ scanClient.associatedDevices.add("02:00:00:00:00:00");
+ scanClient.scannerId = scannerId;
+ scanClientSet.add(scanClient);
+ doReturn(scanClientSet).when(mScanManager).getFullBatchScanQueue();
+ doReturn(mApp).when(mScannerMap).getById(scanClient.scannerId);
+
+ mScanHelper.onBatchScanReportsInternal(
+ status, scannerId, reportType, numRecords, recordData);
+ verify(mScanManager).callbackDone(scannerId, status);
+
+ reportType = ScanManager.SCAN_RESULT_TYPE_TRUNCATED;
+ recordData =
+ new byte[] {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x04, 0x02, 0x02, 0x00, 0x00, 0x02
+ };
+ doReturn(scanClientSet).when(mScanManager).getBatchScanQueue();
+ IScannerCallback callback = mock(IScannerCallback.class);
+ mApp.callback = callback;
+
+ mScanHelper.onBatchScanReportsInternal(
+ status, scannerId, reportType, numRecords, recordData);
+ verify(callback).onBatchScanResults(any());
+ }
+
+ @Test
+ public void enforceReportDelayFloor() {
+ long reportDelayFloorHigher = TransitionalScanHelper.DEFAULT_REPORT_DELAY_FLOOR + 1;
+ ScanSettings scanSettings =
+ new ScanSettings.Builder().setReportDelay(reportDelayFloorHigher).build();
+
+ ScanSettings newScanSettings = mScanHelper.enforceReportDelayFloor(scanSettings);
+
+ assertThat(newScanSettings.getReportDelayMillis())
+ .isEqualTo(scanSettings.getReportDelayMillis());
+
+ ScanSettings scanSettingsFloor = new ScanSettings.Builder().setReportDelay(1).build();
+
+ ScanSettings newScanSettingsFloor = mScanHelper.enforceReportDelayFloor(scanSettingsFloor);
+
+ assertThat(newScanSettingsFloor.getReportDelayMillis())
+ .isEqualTo(TransitionalScanHelper.DEFAULT_REPORT_DELAY_FLOOR);
+ }
+
+ @Test
+ public void registerScanner() throws Exception {
+ IScannerCallback callback = mock(IScannerCallback.class);
+ WorkSource workSource = mock(WorkSource.class);
+
+ AppScanStats appScanStats = mock(AppScanStats.class);
+ doReturn(appScanStats).when(mScannerMap).getAppScanStatsByUid(Binder.getCallingUid());
+
+ mScanHelper.registerScanner(callback, workSource, mAttributionSource);
+ verify(mScannerMap)
+ .add(any(), eq(workSource), eq(callback), eq(null), any(), eq(mScanHelper));
+ verify(mScanManager).registerScanner(any());
+ }
+
+ @Test
+ public void flushPendingBatchResults() {
+ int scannerId = 3;
+
+ mScanHelper.flushPendingBatchResults(scannerId, mAttributionSource);
+ verify(mScanManager).flushBatchScanResults(new ScanClient(scannerId));
+ }
+
+ @Test
+ public void onScanResult_remoteException_clientDied() throws Exception {
+ mSetFlagsRule.enableFlags(Flags.FLAG_LE_SCAN_FIX_REMOTE_EXCEPTION);
+ int scannerId = 1;
+
+ int eventType = 0;
+ int addressType = 0;
+ String address = "02:00:00:00:00:00";
+ int primaryPhy = 0;
+ int secondPhy = 0;
+ int advertisingSid = 0;
+ int txPower = 0;
+ int rssi = 0;
+ int periodicAdvInt = 0;
+ byte[] advData = new byte[0];
+
+ ScanClient scanClient = new ScanClient(scannerId);
+ scanClient.scannerId = scannerId;
+ scanClient.hasNetworkSettingsPermission = true;
+ scanClient.settings =
+ new ScanSettings.Builder()
+ .setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES)
+ .setLegacy(false)
+ .build();
+
+ AppScanStats appScanStats = mock(AppScanStats.class);
+ IScannerCallback callback = mock(IScannerCallback.class);
+
+ mApp.callback = callback;
+ mApp.appScanStats = appScanStats;
+ Set<ScanClient> scanClientSet = Collections.singleton(scanClient);
+
+ doReturn(address).when(mAdapterService).getIdentityAddress(anyString());
+ doReturn(scanClientSet).when(mScanManager).getRegularScanQueue();
+ doReturn(mApp).when(mScannerMap).getById(scanClient.scannerId);
+ doReturn(appScanStats).when(mScannerMap).getAppScanStatsById(scanClient.scannerId);
+
+ // Simulate remote client crash
+ doThrow(new RemoteException()).when(callback).onScanResult(any());
+
+ mScanHelper.onScanResult(
+ eventType,
+ addressType,
+ address,
+ primaryPhy,
+ secondPhy,
+ advertisingSid,
+ txPower,
+ rssi,
+ periodicAdvInt,
+ advData,
+ address);
+
+ assertThat(scanClient.appDied).isTrue();
+ verify(appScanStats).recordScanStop(scannerId);
+ }
+
+ @Test
+ public void registerSync() {
+ ScanResult scanResult = new ScanResult(mDevice, 1, 2, 3, 4, 5, 6, 7, null, 8);
+ int skip = 1;
+ int timeout = 2;
+ IPeriodicAdvertisingCallback callback = mock(IPeriodicAdvertisingCallback.class);
+
+ mScanHelper.registerSync(scanResult, skip, timeout, callback, mAttributionSource);
+ verify(mPeriodicScanManager).startSync(scanResult, skip, timeout, callback);
+ }
+
+ @Test
+ public void transferSync() {
+ int serviceData = 1;
+ int syncHandle = 2;
+
+ mScanHelper.transferSync(mDevice, serviceData, syncHandle, mAttributionSource);
+ verify(mPeriodicScanManager).transferSync(mDevice, serviceData, syncHandle);
+ }
+
+ @Test
+ public void transferSetInfo() {
+ int serviceData = 1;
+ int advHandle = 2;
+ IPeriodicAdvertisingCallback callback = mock(IPeriodicAdvertisingCallback.class);
+
+ mScanHelper.transferSetInfo(mDevice, serviceData, advHandle, callback, mAttributionSource);
+ verify(mPeriodicScanManager).transferSetInfo(mDevice, serviceData, advHandle, callback);
+ }
+
+ @Test
+ public void unregisterSync() {
+ IPeriodicAdvertisingCallback callback = mock(IPeriodicAdvertisingCallback.class);
+
+ mScanHelper.unregisterSync(callback, mAttributionSource);
+ verify(mPeriodicScanManager).stopSync(callback);
+ }
+
+ @Test
+ public void getCurrentUsedTrackingAdvertisement() {
+ mScanHelper.getCurrentUsedTrackingAdvertisement();
+ verify(mScanManager).getCurrentUsedTrackingAdvertisement();
+ }
+
+ @Test
+ public void cleanUp_doesNotCrash() {
+ mScanHelper.cleanup();
+ }
+
+ @Test
+ public void profileConnectionStateChanged_notifyScanManager() {
+ mScanHelper.notifyProfileConnectionStateChange(
+ BluetoothProfile.A2DP,
+ BluetoothProfile.STATE_CONNECTING,
+ BluetoothProfile.STATE_CONNECTED);
+ verify(mScanManager)
+ .handleBluetoothProfileConnectionStateChanged(
+ BluetoothProfile.A2DP,
+ BluetoothProfile.STATE_CONNECTING,
+ BluetoothProfile.STATE_CONNECTED);
+ }
+}
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 8d052d2455..3607fbb035 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
@@ -53,12 +53,14 @@ import com.google.android.mms.pdu.PduHeaders;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.io.IOException;
import java.text.SimpleDateFormat;
@@ -116,6 +118,8 @@ public class BluetoothMapContentObserverTest {
static final int TEST_PRIORITY = 1;
static final int TEST_LAST_ONLINE = 1;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock
private BluetoothMnsObexClient mClient;
@Mock
@@ -171,7 +175,6 @@ public class BluetoothMapContentObserverTest {
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
BluetoothMethodProxy.setInstanceForTesting(mMapMethodProxy);
if (Looper.myLooper() == null) {
Looper.prepare();
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 71f2f5af38..20237fe896 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
@@ -54,11 +54,13 @@ import com.google.android.mms.pdu.PduHeaders;
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.io.ByteArrayInputStream;
import java.io.FileDescriptor;
@@ -111,6 +113,8 @@ 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();
+
@Mock
private BluetoothMapAccountItem mAccountItem;
@Mock
@@ -134,7 +138,6 @@ public class BluetoothMapContentTest {
@Before
public void setUp() {
- MockitoAnnotations.initMocks(this);
BluetoothMethodProxy.setInstanceForTesting(mMapMethodProxy);
mContent = new BluetoothMapContent(mContext, mAccountItem, mMasInstance);
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 35c4a3e2e5..68d0e0d92e 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
@@ -26,11 +26,12 @@ import androidx.test.runner.AndroidJUnit4;
import com.android.bluetooth.SignedLongLong;
-import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+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;
@@ -53,14 +54,11 @@ public class BluetoothMapConvoContactElementTest {
private final SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmss");
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock
private MapContact mMapContact;
- @Before
- public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
- }
-
@Test
public void constructorWithArguments() {
BluetoothMapConvoContactElement contactElement =
@@ -201,4 +199,4 @@ public class BluetoothMapConvoContactElementTest {
assertThat(contactElement.compareTo(contactElementSameLastActivity)).isEqualTo(0);
}
-} \ No newline at end of file
+}
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 34105afb67..b985cd3a4a 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
@@ -26,10 +26,12 @@ import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
@SmallTest
@RunWith(AndroidJUnit4.class)
@@ -47,6 +49,8 @@ public class BluetoothMapMasInstanceTest {
private BluetoothMapAccountItem mAccountItem;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock
private Context mContext;
@Mock
@@ -54,7 +58,6 @@ public class BluetoothMapMasInstanceTest {
@Before
public void setUp() {
- MockitoAnnotations.initMocks(this);
mAccountItem = BluetoothMapAccountItem.create(TEST_ID, TEST_NAME, TEST_PACKAGE_NAME,
TEST_PROVIDER_AUTHORITY, TEST_DRAWABLE, TEST_TYPE, TEST_UCI, TEST_UCI_PREFIX);
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 5aedef3c26..40503a775f 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
@@ -42,11 +42,13 @@ import com.android.bluetooth.mapapi.BluetoothMapContract;
import com.android.obex.ResponseCodes;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
@SmallTest
@RunWith(AndroidJUnit4.class)
@@ -67,6 +69,8 @@ public class BluetoothMapObexServerTest {
private BluetoothMapObexServer mObexServer;
private BluetoothMapAppParams mParams;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock
private Context mContext;
@Mock
@@ -80,7 +84,6 @@ public class BluetoothMapObexServerTest {
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
BluetoothMethodProxy.setInstanceForTesting(mMapMethodProxy);
doReturn(mProviderClient).when(
mMapMethodProxy).contentResolverAcquireUnstableContentProviderClient(any(), any());
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 498fefa79c..e87c55b7d9 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
@@ -28,16 +28,20 @@ import androidx.test.runner.AndroidJUnit4;
import com.android.bluetooth.x.com.android.modules.utils.SynchronousResultReceiver;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
@SmallTest
@RunWith(AndroidJUnit4.class)
public class BluetoothMapServiceBinderTest {
private static final String REMOTE_DEVICE_ADDRESS = "00:00:00:00:00:00";
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock
private BluetoothMapService mService;
@@ -47,7 +51,6 @@ public class BluetoothMapServiceBinderTest {
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
mRemoteDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(REMOTE_DEVICE_ADDRESS);
mBinder = new BluetoothMapService.BluetoothMapBinder(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 5989177b80..009d79d494 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
@@ -48,10 +48,12 @@ import com.android.bluetooth.btservice.storage.DatabaseManager;
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
@MediumTest
@RunWith(AndroidJUnit4.class)
@@ -62,6 +64,7 @@ public class BluetoothMapServiceTest {
private BluetoothAdapter mAdapter = null;
private BluetoothDevice mRemoteDevice;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
@Mock private AdapterService mAdapterService;
@Mock private DatabaseManager mDatabaseManager;
@@ -69,7 +72,6 @@ public class BluetoothMapServiceTest {
@Before
public void setUp() throws Exception {
Context targetContext = InstrumentationRegistry.getTargetContext();
- MockitoAnnotations.initMocks(this);
TestUtils.setAdapterService(mAdapterService);
doReturn(mDatabaseManager).when(mAdapterService).getDatabase();
mService = new BluetoothMapService(targetContext);
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 f8bed9641c..ab6f9cf469 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
@@ -33,10 +33,12 @@ import com.android.bluetooth.map.BluetoothMapSmsPdu.SmsPdu;
import org.junit.Assume;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
@@ -57,6 +59,8 @@ public class BluetoothMapSmsPduTest {
private int TEST_LANGUAGE_TABLE;
private SmsManager mSmsManager = SmsManager.getDefault();
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock
private Context mTargetContext;
@Mock
@@ -64,7 +68,6 @@ public class BluetoothMapSmsPduTest {
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
when(mTargetContext.getSystemServiceName(TelephonyManager.class)).thenReturn(
"TELEPHONY_SERVICE");
when(mTargetContext.getSystemService("TELEPHONY_SERVICE")).thenReturn(mTelephonyManager);
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 c65053e81c..38f9ca46b2 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
@@ -31,11 +31,13 @@ import com.android.bluetooth.BluetoothMethodProxy;
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
@SmallTest
@RunWith(AndroidJUnit4.class)
@@ -46,6 +48,8 @@ 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();
+
@Mock
private ContentResolver mResolver;
@Spy
@@ -55,7 +59,6 @@ public class SmsMmsContactsTest {
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
BluetoothMethodProxy.setInstanceForTesting(mMapMethodProxy);
mContacts = new SmsMmsContacts();
}
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 0ef6e4e95a..c109dcceb4 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
@@ -36,10 +36,12 @@ import androidx.test.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.io.FileInputStream;
import java.io.FileOutputStream;
@@ -55,12 +57,13 @@ public class BluetoothMapEmailProviderTest {
private Context mContext;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Spy
private BluetoothMapEmailProvider mProvider = new TestBluetoothMapEmailProvider();
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
mContext = InstrumentationRegistry.getTargetContext();
}
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 f9e6bb35c8..cae5876491 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
@@ -41,11 +41,13 @@ import androidx.test.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.time.Instant;
import java.util.AbstractMap;
@@ -66,12 +68,13 @@ public class BluetoothMapIMProviderTest {
private Context mContext;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Spy
private BluetoothMapIMProvider mProvider = new TestBluetoothMapIMProvider();
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
mContext = InstrumentationRegistry.getTargetContext();
}
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 5c735c9d45..f58e0992ca 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
@@ -55,12 +55,14 @@ import com.android.vcard.VCardProperty;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.util.Arrays;
import java.util.HashMap;
@@ -92,6 +94,8 @@ public class MapClientContentTest {
private MapClientContent mMapClientContent;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock
private AdapterService mAdapterService;
@Mock
@@ -115,7 +119,6 @@ public class MapClientContentTest {
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
mMockSmsContentProvider = new FakeContentProvider(mMockContext);
mMockMmsContentProvider = new FakeContentProvider(mMockContext);
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 1604459c36..e95088f583 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
@@ -29,16 +29,20 @@ import androidx.test.runner.AndroidJUnit4;
import com.android.bluetooth.x.com.android.modules.utils.SynchronousResultReceiver;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
@MediumTest
@RunWith(AndroidJUnit4.class)
public class MapClientServiceBinderTest {
private static final String REMOTE_DEVICE_ADDRESS = "00:00:00:00:00:00";
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock
private MapClientService mService;
@@ -48,7 +52,6 @@ public class MapClientServiceBinderTest {
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
mRemoteDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(REMOTE_DEVICE_ADDRESS);
mBinder = new MapClientService.Binder(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 0622a7eba3..c24df8b84d 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
@@ -44,16 +44,19 @@ import com.android.bluetooth.btservice.storage.DatabaseManager;
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
@MediumTest
@RunWith(AndroidJUnit4.class)
public class MapClientServiceTest {
private static final String REMOTE_DEVICE_ADDRESS = "00:00:00:00:00:00";
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
@Mock private AdapterService mAdapterService;
@Mock private DatabaseManager mDatabaseManager;
@@ -66,7 +69,6 @@ public class MapClientServiceTest {
@Before
public void setUp() throws Exception {
Context targetContext = InstrumentationRegistry.getTargetContext();
- MockitoAnnotations.initMocks(this);
TestUtils.setAdapterService(mAdapterService);
doReturn(mDatabaseManager).when(mAdapterService).getDatabase();
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 baadbd75e7..2c18e366ff 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
@@ -74,7 +74,8 @@ import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.time.Instant;
import java.util.ArrayList;
@@ -125,6 +126,8 @@ public class MapClientStateMachineTest {
private Context mTargetContext;
private Handler mHandler;
private ArgumentCaptor<Intent> mIntentArgument = ArgumentCaptor.forClass(Intent.class);
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock
private AdapterService mAdapterService;
@Mock
@@ -202,7 +205,6 @@ public class MapClientStateMachineTest {
@Before
public void setUp() throws Exception {
mTargetContext = InstrumentationRegistry.getTargetContext();
- MockitoAnnotations.initMocks(this);
TestUtils.setAdapterService(mAdapterService);
mIsAdapterServiceSet = true;
mMockContentProvider = new MockSmsContentProvider();
diff --git a/android/app/tests/unit/src/com/android/bluetooth/mapclient/MapClientTest.java b/android/app/tests/unit/src/com/android/bluetooth/mapclient/MapClientTest.java
index ab5f97b95d..e36a25ab8d 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/mapclient/MapClientTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/mapclient/MapClientTest.java
@@ -37,10 +37,12 @@ import com.android.bluetooth.btservice.storage.DatabaseManager;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.util.ArrayList;
import java.util.List;
@@ -56,6 +58,8 @@ public class MapClientTest {
private boolean mIsAdapterServiceSet;
private boolean mIsMapClientServiceStarted;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock private AdapterService mAdapterService;
@Mock private MnsService mMockMnsService;
@Mock private DatabaseManager mDatabaseManager;
@@ -64,7 +68,6 @@ public class MapClientTest {
@Before
public void setUp() throws Exception {
mTargetContext = InstrumentationRegistry.getTargetContext();
- MockitoAnnotations.initMocks(this);
TestUtils.setAdapterService(mAdapterService);
mIsAdapterServiceSet = true;
when(mAdapterService.getDatabase()).thenReturn(mDatabaseManager);
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 fb9d899cf3..ffef488313 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
@@ -31,10 +31,12 @@ import com.android.obex.Operation;
import com.android.obex.ResponseCodes;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
@@ -43,6 +45,8 @@ import java.io.DataInputStream;
@RunWith(AndroidJUnit4.class)
public class MnsObexServerTest {
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock
MceStateMachine mStateMachine;
@@ -50,7 +54,6 @@ public class MnsObexServerTest {
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
mServer = new MnsObexServer(mStateMachine, null);
}
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 5c77c88ba5..ceb34661f2 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
@@ -34,10 +34,12 @@ import com.android.bluetooth.btservice.AdapterService;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
@MediumTest
@RunWith(AndroidJUnit4.class)
@@ -46,6 +48,8 @@ public class McpServiceTest {
private McpService mMcpService;
private Context mTargetContext;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock
private AdapterService mAdapterService;
@Mock
@@ -60,7 +64,6 @@ public class McpServiceTest {
Looper.prepare();
}
- MockitoAnnotations.initMocks(this);
TestUtils.setAdapterService(mAdapterService);
mAdapter = BluetoothAdapter.getDefaultAdapter();
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 6f16c76557..f57c002c56 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
@@ -48,7 +48,8 @@ import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
@@ -73,6 +74,8 @@ public class MediaControlGattServiceTest {
private MediaControlGattService mMcpService;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock private AdapterService mAdapterService;
@Mock private MediaControlGattService.BluetoothGattServerProxy mMockGattServer;
@Mock private McpService mMockMcpService;
@@ -88,7 +91,6 @@ public class MediaControlGattServiceTest {
Looper.prepare();
}
- MockitoAnnotations.initMocks(this);
TestUtils.setAdapterService(mAdapterService);
mAdapter = BluetoothAdapter.getDefaultAdapter();
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 e230378e3e..7ce0374564 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
@@ -43,12 +43,14 @@ import com.android.bluetooth.btservice.AdapterService;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.util.ArrayList;
import java.util.HashMap;
@@ -71,6 +73,8 @@ public class MediaControlProfileTest {
private CharSequence charSequence = "TestPlayer";
private MediaControlServiceCallbacks mMcpServiceCallbacks;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock private AdapterService mAdapterService;
@Mock private MediaData mMockMediaData;
@Mock private MediaPlayerList mMockMediaPlayerList;
@@ -94,7 +98,6 @@ public class MediaControlProfileTest {
mTargetContext = InstrumentationRegistry.getTargetContext();
MediaControlProfile.ListCallback listCallback;
- MockitoAnnotations.initMocks(this);
TestUtils.setAdapterService(mAdapterService);
mAdapter = BluetoothAdapter.getDefaultAdapter();
diff --git a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppBtEnableActivityTest.java b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppBtEnableActivityTest.java
index 7156c70804..08f539de2d 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppBtEnableActivityTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppBtEnableActivityTest.java
@@ -42,7 +42,6 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
-import org.mockito.MockitoAnnotations;
public class BluetoothOppBtEnableActivityTest {
@@ -56,7 +55,6 @@ public class BluetoothOppBtEnableActivityTest {
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
mTargetContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
mIntent = new Intent();
mIntent.setClass(mTargetContext, BluetoothOppBtEnableActivity.class);
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 c4abf9a292..07b634279f 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
@@ -48,13 +48,16 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
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();
+
@Spy
BluetoothMethodProxy mBluetoothMethodProxy;
@@ -70,7 +73,6 @@ public class BluetoothOppBtEnablingActivityTest {
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
mBluetoothMethodProxy = Mockito.spy(BluetoothMethodProxy.getInstance());
BluetoothMethodProxy.setInstanceForTesting(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 fd6261e308..b27740bf0b 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
@@ -39,10 +39,12 @@ import com.android.bluetooth.BluetoothMethodProxy;
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.util.ArrayList;
import java.util.List;
@@ -52,12 +54,13 @@ import java.util.List;
public class BluetoothOppHandoverReceiverTest {
Context mContext;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Spy
BluetoothMethodProxy mCallProxy = BluetoothMethodProxy.getInstance();
@Before
public void setUp() {
- MockitoAnnotations.initMocks(this);
mContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
BluetoothMethodProxy.setInstanceForTesting(mCallProxy);
doReturn(0).when(mCallProxy).contentResolverDelete(any(), any(Uri.class), any(), any());
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 58ee1b6067..ddd18d5250 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
@@ -57,7 +57,8 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.io.File;
@@ -68,6 +69,8 @@ public class BluetoothOppLauncherActivityTest {
Intent mIntent;
BluetoothMethodProxy mMethodProxy;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock
BluetoothOppManager mBluetoothOppManager;
@@ -78,7 +81,6 @@ public class BluetoothOppLauncherActivityTest {
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
mTargetContext = spy(new ContextWrapper(
ApplicationProvider.getApplicationContext()));
mMethodProxy = spy(BluetoothMethodProxy.getInstance());
diff --git a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppManagerTest.java b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppManagerTest.java
index b588b2c1b9..695703c1f3 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppManagerTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppManagerTest.java
@@ -51,7 +51,6 @@ import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.mockito.MockitoAnnotations;
import java.util.ArrayList;
import java.util.List;
@@ -65,7 +64,6 @@ public class BluetoothOppManagerTest {
@Before
public void setUp() {
- MockitoAnnotations.initMocks(this);
mContext = spy(new ContextWrapper(
InstrumentationRegistry.getInstrumentation().getTargetContext()));
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 3dc2a51674..f76d5e859e 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
@@ -53,13 +53,16 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+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();
+
@Mock
BluetoothMethodProxy mMethodProxy;
@@ -77,7 +80,6 @@ public class BluetoothOppNotificationTest {
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
mTargetContext = spy(new ContextWrapper(
ApplicationProvider.getApplicationContext()));
BluetoothMethodProxy.setInstanceForTesting(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 4cc481020a..60a04b6149 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
@@ -44,10 +44,12 @@ import com.android.obex.ClientSession;
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.io.IOException;
import java.io.InputStream;
@@ -57,6 +59,8 @@ import java.util.concurrent.TimeUnit;
@RunWith(AndroidJUnit4.class)
public class BluetoothOppObexClientSessionTest {
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock
BluetoothMethodProxy mMethodProxy;
@@ -68,7 +72,6 @@ public class BluetoothOppObexClientSessionTest {
@Before
public void setUp() throws IOException {
- MockitoAnnotations.initMocks(this);
mTargetContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
mClientSession = new BluetoothOppObexClientSession(mTargetContext, mTransport);
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 3971d0e7b0..2e5bf6383e 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
@@ -47,10 +47,12 @@ import com.android.obex.ResponseCodes;
import org.junit.After;
import org.junit.Assume;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.io.IOException;
import java.io.InputStream;
@@ -58,6 +60,8 @@ import java.io.OutputStream;
@RunWith(AndroidJUnit4.class)
public class BluetoothOppObexServerSessionTest {
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock
BluetoothMethodProxy mMethodProxy;
@@ -74,7 +78,6 @@ public class BluetoothOppObexServerSessionTest {
@Before
public void setUp() throws IOException {
- MockitoAnnotations.initMocks(this);
mTargetContext = spy(
new ContextWrapper(
InstrumentationRegistry.getInstrumentation().getTargetContext()));
diff --git a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppPreferenceTest.java b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppPreferenceTest.java
index 8869f282c1..fa690958bc 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppPreferenceTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppPreferenceTest.java
@@ -39,7 +39,6 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.mockito.MockitoAnnotations;
@RunWith(AndroidJUnit4.class)
public class BluetoothOppPreferenceTest {
@@ -49,7 +48,6 @@ public class BluetoothOppPreferenceTest {
@Before
public void setUp() {
- MockitoAnnotations.initMocks(this);
mContext = spy(new ContextWrapper(
InstrumentationRegistry.getInstrumentation().getTargetContext()));
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 faadf25f6e..3887ade6f5 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
@@ -62,7 +62,8 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.util.ArrayList;
import java.util.List;
@@ -74,13 +75,14 @@ public class BluetoothOppReceiverTest {
Context mContext;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock
BluetoothMethodProxy mBluetoothMethodProxy;
BluetoothOppReceiver mReceiver;
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
mContext = spy(new ContextWrapper(
InstrumentationRegistry.getInstrumentation().getTargetContext()));
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 de7de37b5d..7d39d32d37 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
@@ -39,10 +39,12 @@ import com.android.bluetooth.BluetoothMethodProxy;
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.io.FileInputStream;
import java.io.IOException;
@@ -52,12 +54,13 @@ public class BluetoothOppSendFileInfoTest {
Context mContext;
MatrixCursor mCursor;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock
BluetoothMethodProxy mCallProxy;
@Before
public void setUp() {
- MockitoAnnotations.initMocks(this);
mContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
BluetoothMethodProxy.setInstanceForTesting(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 04ab4ee821..f2f566e6cd 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
@@ -40,7 +40,8 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
@SmallTest
@RunWith(AndroidJUnit4.class)
@@ -51,11 +52,12 @@ public class BluetoothOppServiceCleanupTest {
private Context mTargetContext;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock private AdapterService mAdapterService;
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
mTargetContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
TestUtils.setAdapterService(mAdapterService);
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 05b0460834..95acf7749e 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
@@ -45,11 +45,13 @@ import com.android.bluetooth.btservice.AdapterService;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
@MediumTest
@RunWith(AndroidJUnit4.class)
@@ -59,6 +61,7 @@ public class BluetoothOppServiceTest {
private boolean mIsAdapterServiceSet;
private boolean mIsBluetoothOppServiceStarted;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
@Mock BluetoothMethodProxy mBluetoothMethodProxy;
@@ -67,7 +70,6 @@ public class BluetoothOppServiceTest {
@Before
public void setUp() throws Exception {
Context targetContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
- MockitoAnnotations.initMocks(this);
BluetoothMethodProxy.setInstanceForTesting(mBluetoothMethodProxy);
// BluetoothOppService can create a UpdateThread, which will call
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 40580e651f..2fef847508 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
@@ -50,8 +50,9 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.util.ArrayList;
import java.util.List;
@@ -59,6 +60,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
@RunWith(AndroidJUnit4.class)
public class BluetoothOppTransferActivityTest {
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock
Cursor mCursor;
@Spy
@@ -76,7 +79,6 @@ public class BluetoothOppTransferActivityTest {
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
mBluetoothMethodProxy = Mockito.spy(BluetoothMethodProxy.getInstance());
BluetoothMethodProxy.setInstanceForTesting(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 7739c3109d..9cc3c0397b 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
@@ -57,8 +57,9 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.util.ArrayList;
import java.util.List;
@@ -68,6 +69,8 @@ import java.util.List;
*/
@RunWith(AndroidJUnit4.class)
public class BluetoothOppTransferHistoryTest {
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock
Cursor mCursor;
@Spy
@@ -85,7 +88,6 @@ public class BluetoothOppTransferHistoryTest {
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
mBluetoothMethodProxy = Mockito.spy(BluetoothMethodProxy.getInstance());
BluetoothMethodProxy.setInstanceForTesting(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 f1e2a777fb..b9905a000e 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
@@ -53,10 +53,12 @@ import com.android.obex.ObexTransport;
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.util.Objects;
@@ -77,6 +79,8 @@ public class BluetoothOppTransferTest {
private final int mTimestamp = 123456789;
private final boolean mMediaScanned = false;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock
BluetoothOppObexSession mSession;
@Mock
@@ -89,7 +93,6 @@ public class BluetoothOppTransferTest {
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
BluetoothMethodProxy.setInstanceForTesting(mCallProxy);
doReturn(0).when(mCallProxy).contentResolverDelete(any(), nullable(Uri.class),
nullable(String.class), nullable(String[].class));
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 b6bcba8720..9f447e4744 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
@@ -50,10 +50,12 @@ import com.android.bluetooth.opp.BluetoothOppTestUtils.CursorMockData;
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.io.FileNotFoundException;
import java.util.ArrayList;
@@ -68,6 +70,8 @@ public class BluetoothOppUtilityTest {
private static final Uri INCORRECT_FORMAT_URI = Uri.parse("www.google.com");
Context mContext;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock
Cursor mCursor;
@@ -77,7 +81,6 @@ public class BluetoothOppUtilityTest {
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
mContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
BluetoothMethodProxy.setInstanceForTesting(mCallProxy);
TestUtils.setUpUiTest();
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 77872410ce..68756b67e6 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
@@ -61,8 +61,9 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.util.ArrayList;
import java.util.List;
@@ -71,6 +72,8 @@ 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();
+
@Mock
Cursor mCursor;
@Spy
@@ -90,7 +93,6 @@ public class IncomingFileConfirmActivityTest {
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
mBluetoothMethodProxy = Mockito.spy(BluetoothMethodProxy.getInstance());
BluetoothMethodProxy.setInstanceForTesting(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 8357e12fb7..4adb1889e9 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
@@ -32,11 +32,12 @@ import androidx.test.core.app.ApplicationProvider;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
-import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.util.ArrayList;
import java.util.List;
@@ -48,16 +49,13 @@ import java.util.List;
@RunWith(AndroidJUnit4.class)
public class BluetoothTetheringNetworkFactoryTest {
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock
private PanService mPanService;
private Context mContext = ApplicationProvider.getApplicationContext();
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
- }
-
@Test
public void networkStartReverseTetherEmptyIface() {
if (Looper.myLooper() == null) {
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 51e1ae7529..fe54c79872 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
@@ -28,16 +28,20 @@ import androidx.test.runner.AndroidJUnit4;
import com.android.bluetooth.x.com.android.modules.utils.SynchronousResultReceiver;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
@SmallTest
@RunWith(AndroidJUnit4.class)
public class PanServiceBinderTest {
private static final String REMOTE_DEVICE_ADDRESS = "00:00:00:00:00:00";
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock
private PanService mService;
@@ -47,7 +51,6 @@ public class PanServiceBinderTest {
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
mRemoteDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(REMOTE_DEVICE_ADDRESS);
mBinder = new PanService.BluetoothPanBinder(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 e08f5207d9..f1daf38341 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
@@ -42,10 +42,12 @@ import com.android.bluetooth.pan.PanService.BluetoothPanDevice;
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
@MediumTest
@RunWith(AndroidJUnit4.class)
@@ -57,6 +59,7 @@ public class PanServiceTest {
private BluetoothAdapter mAdapter = null;
private BluetoothDevice mRemoteDevice;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
@Mock private AdapterService mAdapterService;
@Mock private DatabaseManager mDatabaseManager;
@@ -66,7 +69,6 @@ public class PanServiceTest {
@Before
public void setUp() throws Exception {
Context targetContext = InstrumentationRegistry.getTargetContext();
- MockitoAnnotations.initMocks(this);
TestUtils.setAdapterService(mAdapterService);
doReturn(mDatabaseManager).when(mAdapterService).getDatabase();
PanNativeInterface.setInstance(mNativeInterface);
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 431c8cd599..9c00501b63 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
@@ -27,10 +27,12 @@ import androidx.test.runner.AndroidJUnit4;
import com.android.obex.PasswordAuthentication;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
@MediumTest
@RunWith(AndroidJUnit4.class)
@@ -38,12 +40,13 @@ public class BluetoothPbapAuthenticatorTest {
private BluetoothPbapAuthenticator mAuthenticator;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock
PbapStateMachine mMockPbapStateMachine;
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
mAuthenticator = new BluetoothPbapAuthenticator(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 33089f4cc0..1ea6786e8b 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
@@ -42,11 +42,13 @@ import com.android.bluetooth.BluetoothMethodProxy;
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
@SmallTest
@RunWith(AndroidJUnit4.class)
@@ -65,12 +67,13 @@ public class BluetoothPbapCallLogComposerTest {
@Spy
BluetoothMethodProxy mPbapCallProxy = BluetoothMethodProxy.getInstance();
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock
Cursor mMockCursor;
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
BluetoothMethodProxy.setInstanceForTesting(mPbapCallProxy);
doReturn(mMockCursor).when(mPbapCallProxy)
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 097f46d8d5..30445b1399 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
@@ -29,15 +29,19 @@ import androidx.test.runner.AndroidJUnit4;
import com.android.bluetooth.R;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
@SmallTest
@RunWith(AndroidJUnit4.class)
public class BluetoothPbapConfigTest {
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock
Context mContext;
@@ -46,7 +50,6 @@ public class BluetoothPbapConfigTest {
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
when(mContext.getResources()).thenReturn(mResources);
}
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 62834b49d8..6d22c2e78c 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
@@ -67,11 +67,13 @@ import com.android.obex.ResponseCodes;
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.io.IOException;
import java.io.OutputStream;
@@ -82,6 +84,8 @@ public class BluetoothPbapObexServerTest {
private static final String TAG = BluetoothPbapObexServerTest.class.getSimpleName();
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock Handler mMockHandler;
@Mock PbapStateMachine mMockStateMachine;
@@ -107,7 +111,6 @@ public class BluetoothPbapObexServerTest {
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
BluetoothMethodProxy.setInstanceForTesting(mPbapMethodProxy);
mServer = new BluetoothPbapObexServer(
mMockHandler, InstrumentationRegistry.getTargetContext(), 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 4bd3a10e31..116fe9e743 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
@@ -26,16 +26,20 @@ import androidx.test.filters.MediumTest;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
@MediumTest
@RunWith(AndroidJUnit4.class)
public class BluetoothPbapServiceBinderTest {
private static final String REMOTE_DEVICE_ADDRESS = "00:00:00:00:00:00";
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock
private BluetoothPbapService mService;
@@ -45,7 +49,6 @@ public class BluetoothPbapServiceBinderTest {
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
mRemoteDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(REMOTE_DEVICE_ADDRESS);
mBinder = new BluetoothPbapService.PbapBinder(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 69dac461ad..b509e7e7c4 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
@@ -44,12 +44,14 @@ import com.android.bluetooth.btservice.storage.DatabaseManager;
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
@MediumTest
@RunWith(AndroidJUnit4.class)
@@ -63,6 +65,7 @@ public class BluetoothPbapServiceTest {
private boolean mIsBluetoothPabpServiceStarted;
private TestLooper mTestLooper;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
@Mock private AdapterService mAdapterService;
@Mock private DatabaseManager mDatabaseManager;
@@ -71,7 +74,6 @@ public class BluetoothPbapServiceTest {
@Before
public void setUp() throws Exception {
Context targetContext = InstrumentationRegistry.getTargetContext();
- MockitoAnnotations.initMocks(this);
mTestLooper = new TestLooper();
BluetoothMethodProxy.setInstanceForTesting(mMethodProxy);
doReturn(mTestLooper.getLooper()).when(mMethodProxy).handlerThreadGetLooper(any());
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 46302cb441..2e46515c56 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
@@ -41,10 +41,12 @@ import com.android.obex.ResponseCodes;
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import org.mockito.stubbing.Answer;
import java.io.OutputStream;
@@ -60,6 +62,8 @@ public class BluetoothPbapSimVcardManagerTest {
private static final String TAG = BluetoothPbapSimVcardManagerTest.class.getSimpleName();
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Spy
BluetoothMethodProxy mPbapMethodProxy = BluetoothMethodProxy.getInstance();
@@ -70,7 +74,6 @@ public class BluetoothPbapSimVcardManagerTest {
@Before
public void setUp() {
- MockitoAnnotations.initMocks(this);
BluetoothMethodProxy.setInstanceForTesting(mPbapMethodProxy);
mContext = InstrumentationRegistry.getTargetContext();
mManager = new BluetoothPbapSimVcardManager(mContext);
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 875042f8b0..a98d782fdd 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
@@ -48,11 +48,13 @@ import com.android.vcard.VCardConfig;
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.util.ArrayList;
import java.util.Calendar;
@@ -62,6 +64,8 @@ import java.util.List;
@RunWith(AndroidJUnit4.class)
public class BluetoothPbapUtilsTest {
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock
Context mContext;
@@ -73,7 +77,6 @@ public class BluetoothPbapUtilsTest {
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
BluetoothMethodProxy.setInstanceForTesting(mProxy);
when(mContext.getResources()).thenReturn(mResources);
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 a6c16aaa42..9fab5c1d8f 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
@@ -34,10 +34,12 @@ import com.android.bluetooth.pbap.BluetoothPbapVcardManager.PropertySelector;
import com.android.bluetooth.pbap.BluetoothPbapVcardManager.VCardFilter;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.util.concurrent.atomic.AtomicInteger;
@@ -45,6 +47,8 @@ import java.util.concurrent.atomic.AtomicInteger;
@RunWith(AndroidJUnit4.class)
public class BluetoothPbapVcardManagerNestedClassesTest {
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock
Context mContext;
@@ -53,7 +57,6 @@ public class BluetoothPbapVcardManagerNestedClassesTest {
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
when(mContext.getResources()).thenReturn(mResources);
}
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 a6ed5593ca..3c623679f5 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
@@ -39,10 +39,12 @@ import com.android.bluetooth.R;
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import org.mockito.stubbing.Answer;
import java.util.Arrays;
@@ -55,6 +57,8 @@ public class BluetoothPbapVcardManagerTest {
private static final String TAG = BluetoothPbapVcardManagerTest.class.getSimpleName();
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Spy
BluetoothMethodProxy mPbapMethodProxy = BluetoothMethodProxy.getInstance();
@@ -63,7 +67,6 @@ public class BluetoothPbapVcardManagerTest {
@Before
public void setUp() {
- MockitoAnnotations.initMocks(this);
BluetoothMethodProxy.setInstanceForTesting(mPbapMethodProxy);
mContext = InstrumentationRegistry.getTargetContext();
mManager = new BluetoothPbapVcardManager(mContext);
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 3e8dd1fff4..6c1e252aab 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
@@ -30,10 +30,12 @@ import androidx.test.runner.AndroidJUnit4;
import com.android.obex.Operation;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.io.IOException;
import java.io.OutputStream;
@@ -42,6 +44,8 @@ import java.io.OutputStream;
@RunWith(AndroidJUnit4.class)
public class HandlerForStringBufferTest {
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock
private Operation mOperation;
@@ -50,7 +54,6 @@ public class HandlerForStringBufferTest {
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
when(mOperation.openOutputStream()).thenReturn(mOutputStream);
}
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 b372f18ad5..978f9dfb0e 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
@@ -38,10 +38,12 @@ import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Ignore;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
@MediumTest
@RunWith(AndroidJUnit4.class)
@@ -58,12 +60,13 @@ public class PbapStateMachineTest {
private BluetoothPbapService mBluetoothPbapService;
private boolean mIsAdapterServiceSet;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock private AdapterService mAdapterService;
@Before
public void setUp() throws Exception {
mTargetContext = InstrumentationRegistry.getTargetContext();
- MockitoAnnotations.initMocks(this);
TestUtils.setAdapterService(mAdapterService);
mIsAdapterServiceSet = true;
// This line must be called to make sure relevant objects are initialized properly
diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/BluetoothPbapRequestTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/BluetoothPbapRequestTest.java
index e258921547..b947c62dc2 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/BluetoothPbapRequestTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/BluetoothPbapRequestTest.java
@@ -30,10 +30,12 @@ import com.android.obex.ObexTransport;
import com.android.obex.ResponseCodes;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.io.InputStream;
@@ -43,12 +45,13 @@ public class BluetoothPbapRequestTest {
private BluetoothPbapRequest mRequest = new BluetoothPbapRequest() {};
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock
private ObexTransport mObexTransport;
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
mRequest = new BluetoothPbapRequest() {};
}
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 ceb85e5727..6a5440ad74 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
@@ -39,10 +39,12 @@ import com.android.vcard.VCardProperty;
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.util.ArrayList;
import java.util.HashMap;
@@ -56,12 +58,13 @@ public class CallLogPullRequestTest {
private final HashMap<String, Integer> mCallCounter = new HashMap<>();
private Context mTargetContext;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Spy
private BluetoothMethodProxy mMapMethodProxy = BluetoothMethodProxy.getInstance();
@Before
public void setUp() {
- MockitoAnnotations.initMocks(this);
BluetoothMethodProxy.setInstanceForTesting(mMapMethodProxy);
mTargetContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
}
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 50f96db865..84806cc383 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
@@ -42,10 +42,12 @@ import com.android.bluetooth.btservice.storage.DatabaseManager;
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
@SmallTest
@RunWith(AndroidJUnit4.class)
@@ -59,6 +61,8 @@ public class PbapClientConnectionHandlerTest {
private Context mTargetContext;
private BluetoothDevice mRemoteDevice;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock
private AdapterService mAdapterService;
@@ -77,7 +81,6 @@ public class PbapClientConnectionHandlerTest {
public void setUp() throws Exception {
mTargetContext = spy(new ContextWrapper(
InstrumentationRegistry.getInstrumentation().getTargetContext()));
- MockitoAnnotations.initMocks(this);
TestUtils.setAdapterService(mAdapterService);
doReturn(mDatabaseManager).when(mAdapterService).getDatabase();
mService = new PbapClientService(mTargetContext);
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 06e63c9519..959439d1dd 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
@@ -48,11 +48,13 @@ import com.android.bluetooth.x.com.android.modules.utils.SynchronousResultReceiv
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
@MediumTest
@RunWith(AndroidJUnit4.class)
@@ -66,6 +68,8 @@ public class PbapClientServiceTest {
boolean mIsAdapterServiceSet;
boolean mIsPbapClientServiceStarted;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock private AdapterService mAdapterService;
@Mock private DatabaseManager mDatabaseManager;
@@ -73,7 +77,6 @@ public class PbapClientServiceTest {
@Before
public void setUp() throws Exception {
mTargetContext = InstrumentationRegistry.getTargetContext();
- MockitoAnnotations.initMocks(this);
TestUtils.setAdapterService(mAdapterService);
mIsAdapterServiceSet = true;
doReturn(mDatabaseManager).when(mAdapterService).getDatabase();
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 ae3bd808a7..d40aa8d5d1 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
@@ -38,12 +38,14 @@ import com.android.bluetooth.TestUtils;
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
@MediumTest
@RunWith(AndroidJUnit4.class)
@@ -52,6 +54,8 @@ public class PbapClientStateMachineTest{
private PbapClientStateMachine mPbapClientStateMachine = null;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock
private PbapClientService mMockPbapClientService;
@Mock
@@ -69,7 +73,6 @@ public class PbapClientStateMachineTest{
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
// This line must be called to make sure relevant objects are initialized properly
mAdapter = BluetoothAdapter.getDefaultAdapter();
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 0fa5520c12..94565511f0 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
@@ -60,12 +60,14 @@ import com.android.bluetooth.x.android.hardware.radio.V1_0.ISap;
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentMatcher;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.util.ArrayList;
import java.util.Arrays;
@@ -82,6 +84,8 @@ public class SapRilReceiverHidlTest {
@Spy
private TestHandlerCallback mCallback = new TestHandlerCallback();
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock
private Handler mServiceHandler;
@@ -92,7 +96,6 @@ public class SapRilReceiverHidlTest {
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
mHandlerThread = new HandlerThread("SapRilReceiverTest");
mHandlerThread.start();
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 3d0e350fb9..293b892a7d 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
@@ -63,12 +63,14 @@ import androidx.test.runner.AndroidJUnit4;
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentMatcher;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.util.Arrays;
@@ -84,6 +86,8 @@ public class SapRilReceiverTest {
@Spy
private TestHandlerCallback mCallback = new TestHandlerCallback();
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock
private Handler mServiceHandler;
@@ -94,7 +98,6 @@ public class SapRilReceiverTest {
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
mHandlerThread = new HandlerThread("SapRilReceiverTest");
mHandlerThread.start();
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 e88c5f122b..0de1343d3a 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
@@ -71,13 +71,15 @@ import androidx.test.runner.AndroidJUnit4;
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.ArgumentMatcher;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.io.InputStream;
import java.io.OutputStream;
@@ -98,6 +100,8 @@ public class SapServerTest {
@Spy
private TestHandlerCallback mCallback = new TestHandlerCallback();
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock
private InputStream mInputStream;
@@ -108,7 +112,6 @@ public class SapServerTest {
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
mHandlerThread = new HandlerThread("SapServerTest");
mHandlerThread.start();
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 27cb3a96dc..6e3071ea4e 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
@@ -36,11 +36,12 @@ import com.android.bluetooth.btservice.storage.DatabaseManager;
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
@MediumTest
@RunWith(AndroidJUnit4.class)
@@ -51,6 +52,8 @@ public class SapServiceTest {
private BluetoothAdapter mAdapter = null;
private Context mTargetContext;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock private AdapterService mAdapterService;
@Mock private DatabaseManager mDatabaseManager;
private BluetoothDevice mDevice;
@@ -58,7 +61,6 @@ public class SapServiceTest {
@Before
public void setUp() throws Exception {
mTargetContext = InstrumentationRegistry.getTargetContext();
- MockitoAnnotations.initMocks(this);
TestUtils.setAdapterService(mAdapterService);
mService = new SapService(mTargetContext);
mService.start();
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 60dfc9df71..5292940b12 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
@@ -41,11 +41,13 @@ import com.android.bluetooth.btservice.AdapterService;
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
@SmallTest
@RunWith(AndroidJUnit4.class)
@@ -59,14 +61,14 @@ public class DipTest {
private ArgumentCaptor<String> mStringArgument = ArgumentCaptor.forClass(String.class);
private ArgumentCaptor<Bundle> mBundleArgument = ArgumentCaptor.forClass(Bundle.class);
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock private AdapterService mAdapterService = null;
@Mock private SdpManagerNativeInterface mNativeInterface;
@Before
public void setUp() throws Exception {
mTargetContext = InstrumentationRegistry.getTargetContext();
- // Set up mocks and test assets
- MockitoAnnotations.initMocks(this);
SdpManagerNativeInterface.setInstance(mNativeInterface);
TestUtils.setAdapterService(mAdapterService);
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 f56789f1ce..d619b6136f 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
@@ -46,7 +46,8 @@ import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
@@ -72,6 +73,8 @@ public class TbsGattTest {
private TbsGatt mTbsGatt;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock
private AdapterService mAdapterService;
@Mock
@@ -95,7 +98,6 @@ public class TbsGattTest {
getInstrumentation().getUiAutomation().adoptShellPermissionIdentity();
- MockitoAnnotations.initMocks(this);
TestUtils.setAdapterService(mAdapterService);
mAdapter = BluetoothAdapter.getDefaultAdapter();
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 856845fda8..7d6b512f48 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
@@ -35,12 +35,14 @@ import com.android.bluetooth.le_audio.LeAudioService;
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.util.ArrayList;
import java.util.Arrays;
@@ -56,6 +58,8 @@ public class TbsGenericTest {
private TbsGeneric mTbsGeneric;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
private @Mock TbsGatt mTbsGatt;
private @Mock IBluetoothLeCallControlCallback mIBluetoothLeCallControlCallback;
private @Captor ArgumentCaptor<Integer> mGtbsCcidCaptor;
@@ -70,7 +74,6 @@ public class TbsGenericTest {
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
mAdapter = BluetoothAdapter.getDefaultAdapter();
mContext = getInstrumentation().getTargetContext();
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 5b295f4b55..060fdee686 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
@@ -60,7 +60,8 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.util.ArrayList;
import java.util.Arrays;
@@ -102,6 +103,8 @@ public class BluetoothInCallServiceTest {
public final ServiceTestRule mServiceRule
= ServiceTestRule.withTimeout(1, TimeUnit.SECONDS);
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock
private BluetoothHeadsetProxy mMockBluetoothHeadset;
@Mock
@@ -136,7 +139,6 @@ public class BluetoothInCallServiceTest {
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
InstrumentationRegistry.getInstrumentation().getUiAutomation().adoptShellPermissionIdentity();
// Create the service Intent.
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 af77f4fac5..102389c364 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
@@ -36,10 +36,12 @@ import androidx.test.runner.AndroidJUnit4;
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.util.ArrayList;
import java.util.LinkedHashSet;
@@ -53,6 +55,8 @@ 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();
+
@Mock
private TelecomManager mMockTelecomManager;
@@ -61,7 +65,6 @@ public class CallInfoTest {
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
mBluetoothInCallService = new BluetoothInCallService();
mMockCallInfo = spy(mBluetoothInCallService.new CallInfo());
diff --git a/android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlNativeInterfaceTest.java b/android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlNativeInterfaceTest.java
index fbf4697121..7d19671151 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlNativeInterfaceTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlNativeInterfaceTest.java
@@ -25,14 +25,18 @@ import androidx.test.runner.AndroidJUnit4;
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
@RunWith(AndroidJUnit4.class)
public class VolumeControlNativeInterfaceTest {
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock
private VolumeControlService mService;
@@ -40,7 +44,6 @@ public class VolumeControlNativeInterfaceTest {
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
when(mService.isAvailable()).thenReturn(true);
VolumeControlService.setVolumeControlService(mService);
mNativeInterface = VolumeControlNativeInterface.getInstance();
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 79a327cd7a..5c00afb406 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
@@ -58,7 +58,8 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.time.Duration;
import java.util.Arrays;
@@ -88,6 +89,8 @@ public class VolumeControlServiceTest {
private BroadcastReceiver mVolumeControlIntentReceiver;
private FakeFeatureFlagsImpl mFakeFlagsImpl;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock private AdapterService mAdapterService;
@Mock private LeAudioService mLeAudioService;
@Mock private DatabaseManager mDatabaseManager;
@@ -101,8 +104,6 @@ public class VolumeControlServiceTest {
@Before
public void setUp() throws Exception {
mTargetContext = InstrumentationRegistry.getTargetContext();
- // Set up mocks and test assets
- MockitoAnnotations.initMocks(this);
if (Looper.myLooper() == null) {
Looper.prepare();
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 2082abd598..80d25bdb4f 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
@@ -44,12 +44,14 @@ import org.hamcrest.core.IsInstanceOf;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
@MediumTest
@RunWith(AndroidJUnit4.class)
@@ -61,6 +63,8 @@ public class VolumeControlStateMachineTest {
private BluetoothDevice mTestDevice;
private static final int TIMEOUT_MS = 1000;
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
@Mock private AdapterService mAdapterService;
@Mock private VolumeControlService mVolumeControlService;
@Mock private VolumeControlNativeInterface mVolumeControlNativeInterface;
@@ -69,8 +73,6 @@ public class VolumeControlStateMachineTest {
public void setUp() throws Exception {
mTargetContext = InstrumentationRegistry.getTargetContext();
InstrumentationRegistry.getInstrumentation().getUiAutomation().adoptShellPermissionIdentity();
- // Set up mocks and test assets
- MockitoAnnotations.initMocks(this);
TestUtils.setAdapterService(mAdapterService);
mAdapter = BluetoothAdapter.getDefaultAdapter();
diff --git a/flags/gap.aconfig b/flags/gap.aconfig
index 05d6ea38f5..5098a7461f 100644
--- a/flags/gap.aconfig
+++ b/flags/gap.aconfig
@@ -112,3 +112,10 @@ flag {
description: "Remove ACL when there is not resource to handle more gatt connections."
bug: "325929235"
}
+
+flag {
+ name: "ble_scan_adv_metrics_redesign"
+ namespace: "bluetooth"
+ description: "Reimplement BLE scan and advertisement metrics logging."
+ bug: "328303508"
+}
diff --git a/flags/map.aconfig b/flags/map.aconfig
new file mode 100644
index 0000000000..341b2b80e1
--- /dev/null
+++ b/flags/map.aconfig
@@ -0,0 +1,8 @@
+package: "com.android.bluetooth.flags"
+
+flag {
+ name: "map_limit_notification"
+ namespace: "bluetooth"
+ description: "Skip notyfing old messages in MAP"
+ bug: "325863406"
+}
diff --git a/framework/api/system-current.txt b/framework/api/system-current.txt
index 04a169142f..2e39f52773 100644
--- a/framework/api/system-current.txt
+++ b/framework/api/system-current.txt
@@ -492,6 +492,8 @@ package android.bluetooth {
field public static final int AUDIO_LOCATION_TOP_SIDE_LEFT = 262144; // 0x40000
field public static final int AUDIO_LOCATION_TOP_SIDE_RIGHT = 524288; // 0x80000
field public static final String EXTRA_LE_AUDIO_GROUP_ID = "android.bluetooth.extra.LE_AUDIO_GROUP_ID";
+ field @FlaggedApi("com.android.bluetooth.flags.leaudio_callback_on_group_stream_status") public static final int GROUP_STREAM_STATUS_IDLE = 0; // 0x0
+ field @FlaggedApi("com.android.bluetooth.flags.leaudio_callback_on_group_stream_status") public static final int GROUP_STREAM_STATUS_STREAMING = 1; // 0x1
}
public static interface BluetoothLeAudio.Callback {
diff --git a/framework/java/android/bluetooth/BluetoothAdapter.java b/framework/java/android/bluetooth/BluetoothAdapter.java
index e0cdc2ce7b..509f8f3b80 100644
--- a/framework/java/android/bluetooth/BluetoothAdapter.java
+++ b/framework/java/android/bluetooth/BluetoothAdapter.java
@@ -5810,9 +5810,8 @@ public final class BluetoothAdapter {
try {
return mManagerService.isAutoOnSupported();
} catch (RemoteException e) {
- e.rethrowFromSystemServer();
+ throw e.rethrowFromSystemServer();
}
- return false;
}
/**
@@ -5829,9 +5828,8 @@ public final class BluetoothAdapter {
try {
return mManagerService.isAutoOnEnabled();
} catch (RemoteException e) {
- e.rethrowFromSystemServer();
+ throw e.rethrowFromSystemServer();
}
- return false;
}
/**
diff --git a/framework/java/android/bluetooth/BluetoothLeAudio.java b/framework/java/android/bluetooth/BluetoothLeAudio.java
index ae0883b9b9..68bbdd9406 100644
--- a/framework/java/android/bluetooth/BluetoothLeAudio.java
+++ b/framework/java/android/bluetooth/BluetoothLeAudio.java
@@ -668,6 +668,7 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable {
* @hide
*/
@FlaggedApi(Flags.FLAG_LEAUDIO_CALLBACK_ON_GROUP_STREAM_STATUS)
+ @SystemApi
public static final int GROUP_STREAM_STATUS_IDLE = IBluetoothLeAudio.GROUP_STREAM_STATUS_IDLE;
/**
@@ -676,6 +677,7 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable {
* @hide
*/
@FlaggedApi(Flags.FLAG_LEAUDIO_CALLBACK_ON_GROUP_STREAM_STATUS)
+ @SystemApi
public static final int GROUP_STREAM_STATUS_STREAMING =
IBluetoothLeAudio.GROUP_STREAM_STATUS_STREAMING;
diff --git a/sysprop/Android.bp b/sysprop/Android.bp
index b399a8d7b8..c2e71a97c8 100644
--- a/sysprop/Android.bp
+++ b/sysprop/Android.bp
@@ -10,6 +10,7 @@ sysprop_library {
"avrcp.sysprop",
"ble.sysprop",
"bta.sysprop",
+ "device_id.sysprop",
"hfp.sysprop",
],
property_owner: "Platform",
diff --git a/sysprop/device_id.sysprop b/sysprop/device_id.sysprop
new file mode 100644
index 0000000000..b220abbe01
--- /dev/null
+++ b/sysprop/device_id.sysprop
@@ -0,0 +1,26 @@
+module: "android.sysprop.bluetooth.DeviceIDProperties"
+owner: Platform
+
+prop {
+ api_name: "vendor_id"
+ type: Integer
+ scope: Internal
+ access: Readonly
+ prop_name: "bluetooth.device_id.vendor_id"
+}
+
+prop {
+ api_name: "vendor_id_source"
+ type: Integer
+ scope: Internal
+ access: Readonly
+ prop_name: "bluetooth.device_id.vendor_id_source"
+}
+
+prop {
+ api_name: "product_id"
+ type: Integer
+ scope: Internal
+ access: Readonly
+ prop_name: "bluetooth.device_id.product_id"
+}
diff --git a/sysprop/exported_include/android_bluetooth_sysprop.h b/sysprop/exported_include/android_bluetooth_sysprop.h
index 3e76262114..e76411ef95 100644
--- a/sysprop/exported_include/android_bluetooth_sysprop.h
+++ b/sysprop/exported_include/android_bluetooth_sysprop.h
@@ -22,6 +22,7 @@
#include <avrcp.sysprop.h>
#include <ble.sysprop.h>
#include <bta.sysprop.h>
+#include <device_id.sysprop.h>
#include <hfp.sysprop.h>
#define GET_SYSPROP(namespace, prop, default) \
diff --git a/system/bta/le_audio/client.cc b/system/bta/le_audio/client.cc
index 4378553822..4c69c6f3c4 100644
--- a/system/bta/le_audio/client.cc
+++ b/system/bta/le_audio/client.cc
@@ -3442,10 +3442,6 @@ class LeAudioClientImpl : public LeAudioClient {
return;
}
- if (DsaDataConsume(group, cis_conn_hdl, data, size, timestamp)) {
- return;
- }
-
uint16_t left_cis_handle = 0;
uint16_t right_cis_handle = 0;
for (auto [cis_handle, audio_location] :
@@ -5262,6 +5258,10 @@ class LeAudioClientImpl : public LeAudioClient {
auto* event =
static_cast<bluetooth::hci::iso_manager::cis_data_evt*>(data);
+ if (DsaDataConsume(event)) {
+ return;
+ }
+
if (audio_receiver_state_ != AudioState::STARTED) {
LOG_ERROR("receiver state not ready, current state=%s",
ToString(audio_receiver_state_).c_str());
@@ -5809,16 +5809,34 @@ class LeAudioClientImpl : public LeAudioClient {
le_audio::MetricsCollector::Get()->OnStreamEnded(active_group_id_);
}
- bool DsaDataConsume(LeAudioDeviceGroup* group, uint16_t cis_conn_hdl,
- uint8_t* data, uint16_t size, uint32_t timestamp) {
+ bool DsaDataConsume(bluetooth::hci::iso_manager::cis_data_evt* event) {
if (!IS_FLAG_ENABLED(leaudio_dynamic_spatial_audio)) {
return false;
}
- if (iso_data_callback == nullptr || !group->dsa_.active ||
- group->dsa_.mode != DsaMode::ISO_SW) {
+ if (active_group_id_ == bluetooth::groups::kGroupUnknown) {
return false;
}
+ LeAudioDeviceGroup* group = aseGroups_.FindById(active_group_id_);
+ if (!group || !group->dsa_.active) {
+ return false;
+ }
+
+ if (group->dsa_.mode != DsaMode::ISO_SW) {
+ LOG_WARN("ISO packets received over HCI in DSA mode: %d",
+ group->dsa_.mode);
+ return false;
+ }
+
+ if (iso_data_callback == nullptr) {
+ LOG_WARN("Dsa data consumer not registered");
+ return false;
+ }
+
+ uint16_t cis_conn_hdl = event->cis_conn_hdl;
+ uint8_t* data = event->p_msg->data + event->p_msg->offset;
+ uint16_t size = event->p_msg->len - event->p_msg->offset;
+ uint32_t timestamp = event->ts;
// Find LE Audio device
LeAudioDevice* leAudioDevice = group->GetFirstDevice();
@@ -6202,6 +6220,7 @@ bool LeAudioClient::RegisterIsoDataConsumer(LeAudioIsoDataCallback callback) {
return false;
}
+ LOG_INFO("ISO data consumer changed");
iso_data_callback = callback;
return true;
}
diff --git a/system/btif/Android.bp b/system/btif/Android.bp
index 263ca2048a..6faaac5095 100644
--- a/system/btif/Android.bp
+++ b/system/btif/Android.bp
@@ -244,6 +244,7 @@ cc_library_static {
"libbt-platform-protos-lite",
"libbt-stack-core",
"libbt_shim_bridge",
+ "libcom.android.sysprop.bluetooth.wrapped",
"libflatbuffers-cpp",
"libstatslog_bt",
],
diff --git a/system/btif/src/btif_a2dp.cc b/system/btif/src/btif_a2dp.cc
index 08af45e970..a76d317037 100644
--- a/system/btif/src/btif_a2dp.cc
+++ b/system/btif/src/btif_a2dp.cc
@@ -136,26 +136,46 @@ void btif_a2dp_on_stopped(tBTA_AV_SUSPEND* p_av_suspend,
const A2dpType local_a2dp_type) {
log::info("## ON A2DP STOPPED ## p_av_suspend={}", fmt::ptr(p_av_suspend));
- if (btif_av_get_peer_sep(local_a2dp_type) == AVDT_TSEP_SRC) {
+ const uint8_t peer_type_sep = btif_av_get_peer_sep(local_a2dp_type);
+ if (peer_type_sep == AVDT_TSEP_SRC) {
btif_a2dp_sink_on_stopped(p_av_suspend);
return;
}
- if (bluetooth::audio::a2dp::is_hal_enabled() ||
- !btif_av_is_a2dp_offload_running()) {
- btif_a2dp_source_on_stopped(p_av_suspend);
+ if (!IS_FLAG_ENABLED(a2dp_concurrent_source_sink)) {
+ if (bluetooth::audio::a2dp::is_hal_enabled() ||
+ !btif_av_is_a2dp_offload_running()) {
+ btif_a2dp_source_on_stopped(p_av_suspend);
+ return;
+ }
+ } else if (peer_type_sep == AVDT_TSEP_SNK) {
+ if (bluetooth::audio::a2dp::is_hal_enabled() ||
+ !btif_av_is_a2dp_offload_running()) {
+ btif_a2dp_source_on_stopped(p_av_suspend);
+ return;
+ }
}
}
void btif_a2dp_on_suspended(tBTA_AV_SUSPEND* p_av_suspend,
const A2dpType local_a2dp_type) {
log::info("## ON A2DP SUSPENDED ## p_av_suspend={}", fmt::ptr(p_av_suspend));
- if (btif_av_get_peer_sep(local_a2dp_type) == AVDT_TSEP_SRC) {
+ const uint8_t peer_type_sep = btif_av_get_peer_sep(local_a2dp_type);
+ if (peer_type_sep == AVDT_TSEP_SRC) {
btif_a2dp_sink_on_suspended(p_av_suspend);
return;
}
- if (bluetooth::audio::a2dp::is_hal_enabled() ||
- !btif_av_is_a2dp_offload_running()) {
- btif_a2dp_source_on_suspended(p_av_suspend);
+ if (!IS_FLAG_ENABLED(a2dp_concurrent_source_sink)) {
+ if (bluetooth::audio::a2dp::is_hal_enabled() ||
+ !btif_av_is_a2dp_offload_running()) {
+ btif_a2dp_source_on_suspended(p_av_suspend);
+ return;
+ }
+ } else if (peer_type_sep == AVDT_TSEP_SNK) {
+ if (bluetooth::audio::a2dp::is_hal_enabled() ||
+ !btif_av_is_a2dp_offload_running()) {
+ btif_a2dp_source_on_suspended(p_av_suspend);
+ return;
+ }
}
}
diff --git a/system/btif/src/btif_core.cc b/system/btif/src/btif_core.cc
index 56ffd20f1e..9afbd01ec9 100644
--- a/system/btif/src/btif_core.cc
+++ b/system/btif/src/btif_core.cc
@@ -28,6 +28,8 @@
#define LOG_TAG "bt_btif_core"
+#include <android_bluetooth_flags.h>
+#include <android_bluetooth_sysprop.h>
#include <base/at_exit.h>
#include <base/functional/bind.h>
#include <base/logging.h>
@@ -216,8 +218,25 @@ void btif_enable_bluetooth_evt() {
GetInterfaceToProfiles()->onBluetoothEnabled();
- /* load did configuration */
- bte_load_did_conf(BTE_DID_CONF_FILE);
+ if (!IS_FLAG_ENABLED(load_did_config_from_sysprops)) {
+ bte_load_did_conf(BTE_DID_CONF_FILE);
+ } else {
+ tSDP_DI_RECORD record = {
+ .vendor = uint16_t(
+ GET_SYSPROP(DeviceIDProperties, vendor_id, LMP_COMPID_GOOGLE)),
+ .vendor_id_source = uint16_t(GET_SYSPROP(
+ DeviceIDProperties, vendor_id_source, DI_VENDOR_ID_SOURCE_BTSIG)),
+ .product = uint16_t(GET_SYSPROP(DeviceIDProperties, product_id, 0)),
+ .primary_record = true,
+ };
+
+ uint32_t record_handle;
+ tBTA_STATUS status = BTA_DmSetLocalDiRecord(&record, &record_handle);
+ if (status != BTA_SUCCESS) {
+ log::error("unable to set device ID record error {}.",
+ bta_status_text(status));
+ }
+ }
btif_dm_load_local_oob();
diff --git a/system/btif/src/btif_sock.cc b/system/btif/src/btif_sock.cc
index a8416c359d..944297113a 100644
--- a/system/btif/src/btif_sock.cc
+++ b/system/btif/src/btif_sock.cc
@@ -269,7 +269,6 @@ static bt_status_t btsock_listen(btsock_type_t type, const char* service_name,
*sock_fd = INVALID_FD;
bt_status_t status = BT_STATUS_FAIL;
- int original_channel = channel;
log_socket_connection_state(RawAddress::kEmpty, 0, type,
android::bluetooth::SocketConnectionstateEnum::
@@ -286,19 +285,8 @@ static bt_status_t btsock_listen(btsock_type_t type, const char* service_name,
btsock_l2cap_listen(service_name, channel, sock_fd, flags, app_uid);
break;
case BTSOCK_L2CAP_LE:
- if (flags & BTSOCK_FLAG_NO_SDP) {
- /* Set channel to zero so that it will be assigned */
- channel = 0;
- } else if (channel <= 0) {
- log::error("type BTSOCK_L2CAP_LE: invalid channel={}", channel);
- break;
- }
- flags |= BTSOCK_FLAG_LE_COC;
- log::info(
- "type=BTSOCK_L2CAP_LE, channel=0x{:x}, original=0x{:x}, flags=0x{:x}",
- channel, original_channel, flags);
- status =
- btsock_l2cap_listen(service_name, channel, sock_fd, flags, app_uid);
+ status = btsock_l2cap_listen(service_name, channel, sock_fd,
+ flags | BTSOCK_FLAG_LE_COC, app_uid);
break;
case BTSOCK_SCO:
status = btsock_sco_listen(sock_fd, flags);
diff --git a/system/btif/src/btif_sock_l2cap.cc b/system/btif/src/btif_sock_l2cap.cc
index 528274a005..0ba85551b2 100644
--- a/system/btif/src/btif_sock_l2cap.cc
+++ b/system/btif/src/btif_sock_l2cap.cc
@@ -786,15 +786,25 @@ static bt_status_t btsock_l2cap_listen_or_connect(const char* name,
int channel, int* sock_fd,
int flags, char listen,
int app_uid) {
+ if (!is_inited()) return BT_STATUS_NOT_READY;
+
bool is_le_coc = (flags & BTSOCK_FLAG_LE_COC) != 0;
+ if (is_le_coc && listen) {
+ if (flags & BTSOCK_FLAG_NO_SDP) {
+ /* For LE COC server; set channel to zero so that it will be assigned */
+ channel = 0;
+ } else if (channel <= 0) {
+ log::error("type BTSOCK_L2CAP_LE: invalid channel={}", channel);
+ return BT_STATUS_FAIL;
+ }
+ }
+
if (!sock_fd) {
log::info("Invalid socket descriptor");
return BT_STATUS_PARM_INVALID;
}
- if (!is_inited()) return BT_STATUS_NOT_READY;
-
// TODO: This is kind of bad to lock here, but it is needed for the current
// design.
std::unique_lock<std::mutex> lock(state_lock);
diff --git a/system/log/src/vlog_android.cc b/system/log/src/vlog_android.cc
index e5ca8f1fc8..0f235b0b6f 100644
--- a/system/log/src/vlog_android.cc
+++ b/system/log/src/vlog_android.cc
@@ -33,8 +33,13 @@ void vlog(Level level, char const* tag, char const* file_name, int line,
}
// Format to stack buffer.
+ // liblog uses a different default depending on the execution context
+ // (host or device); the file and line are not systematically included.
+ // In order to have consistent logs we include it manually in the log
+ // message.
truncating_buffer<kBufferSize> buffer;
- fmt::format_to(std::back_insert_iterator(buffer), "{}: ", function_name);
+ fmt::format_to(std::back_insert_iterator(buffer), "{}:{} {}: ", file_name,
+ line, function_name);
fmt::vformat_to(std::back_insert_iterator(buffer), fmt, vargs);
// Send message to liblog.
@@ -43,8 +48,8 @@ void vlog(Level level, char const* tag, char const* file_name, int line,
.buffer_id = LOG_ID_MAIN,
.priority = static_cast<android_LogPriority>(level),
.tag = tag,
- .file = file_name,
- .line = static_cast<uint32_t>(line),
+ .file = nullptr,
+ .line = 0,
.message = buffer.c_str(),
};
__android_log_write_log_message(&message);
diff --git a/system/log/src/vlog_test.cc b/system/log/src/vlog_test.cc
index f5f41b6c5d..5e341c7a33 100644
--- a/system/log/src/vlog_test.cc
+++ b/system/log/src/vlog_test.cc
@@ -51,10 +51,11 @@ TEST(BluetoothLoggerTest, verbose) {
ASSERT_TRUE(androidLogMessage.has_value());
EXPECT_EQ(androidLogMessage->priority, ANDROID_LOG_VERBOSE);
EXPECT_STREQ(androidLogMessage->tag, LOG_TAG);
- EXPECT_STREQ(androidLogMessage->file,
- "packages/modules/Bluetooth/system/log/src/vlog_test.cc");
- EXPECT_EQ(androidLogMessage->line, 49);
- EXPECT_STREQ(androidLogMessage->message, "TestBody: verbose test");
+ EXPECT_EQ(androidLogMessage->file, nullptr);
+ EXPECT_EQ(androidLogMessage->line, 0);
+ EXPECT_STREQ(androidLogMessage->message,
+ "packages/modules/Bluetooth/system/log/src/vlog_test.cc:49 "
+ "TestBody: verbose test");
}
TEST(BluetoothLoggerTest, debug) {
@@ -65,10 +66,11 @@ TEST(BluetoothLoggerTest, debug) {
ASSERT_TRUE(androidLogMessage.has_value());
EXPECT_EQ(androidLogMessage->priority, ANDROID_LOG_DEBUG);
EXPECT_STREQ(androidLogMessage->tag, LOG_TAG);
- EXPECT_STREQ(androidLogMessage->file,
- "packages/modules/Bluetooth/system/log/src/vlog_test.cc");
- EXPECT_EQ(androidLogMessage->line, 63);
- EXPECT_STREQ(androidLogMessage->message, "TestBody: debug test");
+ EXPECT_STREQ(androidLogMessage->file, nullptr);
+ EXPECT_EQ(androidLogMessage->line, 0);
+ EXPECT_STREQ(androidLogMessage->message,
+ "packages/modules/Bluetooth/system/log/src/vlog_test.cc:64 "
+ "TestBody: debug test");
}
TEST(BluetoothLoggerTest, info) {
@@ -79,10 +81,11 @@ TEST(BluetoothLoggerTest, info) {
ASSERT_TRUE(androidLogMessage.has_value());
EXPECT_EQ(androidLogMessage->priority, ANDROID_LOG_INFO);
EXPECT_STREQ(androidLogMessage->tag, LOG_TAG);
- EXPECT_STREQ(androidLogMessage->file,
- "packages/modules/Bluetooth/system/log/src/vlog_test.cc");
- EXPECT_EQ(androidLogMessage->line, 77);
- EXPECT_STREQ(androidLogMessage->message, "TestBody: info test");
+ EXPECT_STREQ(androidLogMessage->file, nullptr);
+ EXPECT_EQ(androidLogMessage->line, 0);
+ EXPECT_STREQ(androidLogMessage->message,
+ "packages/modules/Bluetooth/system/log/src/vlog_test.cc:79 "
+ "TestBody: info test");
}
TEST(BluetoothLoggerTest, warn) {
@@ -93,10 +96,11 @@ TEST(BluetoothLoggerTest, warn) {
ASSERT_TRUE(androidLogMessage.has_value());
EXPECT_EQ(androidLogMessage->priority, ANDROID_LOG_WARN);
EXPECT_STREQ(androidLogMessage->tag, LOG_TAG);
- EXPECT_STREQ(androidLogMessage->file,
- "packages/modules/Bluetooth/system/log/src/vlog_test.cc");
- EXPECT_EQ(androidLogMessage->line, 91);
- EXPECT_STREQ(androidLogMessage->message, "TestBody: warn test");
+ EXPECT_STREQ(androidLogMessage->file, nullptr);
+ EXPECT_EQ(androidLogMessage->line, 0);
+ EXPECT_STREQ(androidLogMessage->message,
+ "packages/modules/Bluetooth/system/log/src/vlog_test.cc:94 "
+ "TestBody: warn test");
}
TEST(BluetoothLoggerTest, error) {
@@ -107,10 +111,11 @@ TEST(BluetoothLoggerTest, error) {
ASSERT_TRUE(androidLogMessage.has_value());
EXPECT_EQ(androidLogMessage->priority, ANDROID_LOG_ERROR);
EXPECT_STREQ(androidLogMessage->tag, LOG_TAG);
- EXPECT_STREQ(androidLogMessage->file,
- "packages/modules/Bluetooth/system/log/src/vlog_test.cc");
- EXPECT_EQ(androidLogMessage->line, 105);
- EXPECT_STREQ(androidLogMessage->message, "TestBody: error test");
+ EXPECT_STREQ(androidLogMessage->file, nullptr);
+ EXPECT_EQ(androidLogMessage->line, 0);
+ EXPECT_STREQ(androidLogMessage->message,
+ "packages/modules/Bluetooth/system/log/src/vlog_test.cc:109 "
+ "TestBody: error test");
}
TEST(BluetoothLoggerTest, null_string_parameter) {
@@ -118,17 +123,23 @@ TEST(BluetoothLoggerTest, null_string_parameter) {
char const* const_null_str = nullptr;
log::info("input: {}", const_null_str);
- EXPECT_STREQ(androidLogMessage->message, "TestBody: input: (nullptr)");
+ EXPECT_STREQ(androidLogMessage->message,
+ "packages/modules/Bluetooth/system/log/src/vlog_test.cc:125 "
+ "TestBody: input: (nullptr)");
androidLogMessage.reset();
char* null_str = nullptr;
log::info("input: {}", null_str);
- EXPECT_STREQ(androidLogMessage->message, "TestBody: input: (nullptr)");
+ EXPECT_STREQ(androidLogMessage->message,
+ "packages/modules/Bluetooth/system/log/src/vlog_test.cc:133 "
+ "TestBody: input: (nullptr)");
androidLogMessage.reset();
char const* nonnull_str = "hello world";
log::info("input: {}", nonnull_str);
- EXPECT_STREQ(androidLogMessage->message, "TestBody: input: hello world");
+ EXPECT_STREQ(androidLogMessage->message,
+ "packages/modules/Bluetooth/system/log/src/vlog_test.cc:141 "
+ "TestBody: input: hello world");
}
diff --git a/system/test/suite/Android.bp b/system/test/suite/Android.bp
index fcfe5c88fa..505d7ab089 100644
--- a/system/test/suite/Android.bp
+++ b/system/test/suite/Android.bp
@@ -41,9 +41,6 @@ cc_defaults {
"adapter/bluetooth_test.cc",
],
shared_libs: [
- "android.hardware.bluetooth.audio@2.0",
- "android.hardware.bluetooth.audio@2.1",
- "android.system.suspend-V1-ndk",
"libPlatformProperties",
"libaaudio",
"libbinder",
@@ -57,7 +54,13 @@ cc_defaults {
"libutils",
],
static_libs: [
+ "android.hardware.audio.common@5.0",
"android.hardware.bluetooth.a2dp@1.0",
+ "android.hardware.bluetooth.audio@2.0",
+ "android.hardware.bluetooth.audio@2.1",
+ "android.hardware.common-V2-ndk",
+ "android.hardware.common.fmq-V1-ndk",
+ "android.system.suspend-V1-ndk",
"android.system.suspend.control-V1-ndk",
"avrcp-target-service",
"lib-bt-packets",