summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--android/app/Android.bp2
-rw-r--r--android/app/aidl/android/bluetooth/BluetoothAudioConfig.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/BluetoothAvrcpPlayerSettings.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/BluetoothClass.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/BluetoothCodecConfig.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/BluetoothCodecStatus.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/BluetoothCodecType.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/BluetoothGattCharacteristic.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/BluetoothGattDescriptor.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/BluetoothGattIncludedService.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/BluetoothGattService.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/BluetoothHeadsetClientCall.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/BluetoothHearingAid.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/BluetoothHidDeviceAppQosSettings.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/BluetoothHidDeviceAppSdpSettings.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/BluetoothLeAudioCodecConfig.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/BluetoothLeAudioCodecStatus.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/BluetoothLeAudioContentMetadata.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/BluetoothLeBroadcastMetadata.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/BluetoothLeBroadcastReceiveState.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/BluetoothLeBroadcastSettings.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/BluetoothSinkAudioPolicy.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/IAudioInputCallback.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/IBluetooth.aidl6
-rw-r--r--android/app/aidl/android/bluetooth/IBluetoothA2dp.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/IBluetoothA2dpSink.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/IBluetoothAvrcpController.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/IBluetoothCallback.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/IBluetoothConnectionCallback.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/IBluetoothGatt.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/IBluetoothGattCallback.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/IBluetoothGattServerCallback.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/IBluetoothHapClientCallback.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/IBluetoothHciVendorSpecificCallback.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/IBluetoothHeadset.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/IBluetoothHeadsetClient.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/IBluetoothHearingAid.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/IBluetoothHidDevice.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/IBluetoothHidHost.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/IBluetoothLeAudioCallback.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/IBluetoothLeBroadcastAssistant.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/IBluetoothLeBroadcastAssistantCallback.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/IBluetoothLeBroadcastCallback.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/IBluetoothMap.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/IBluetoothMapClient.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/IBluetoothMetadataListener.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/IBluetoothOobDataCallback.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/IBluetoothPan.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/IBluetoothPanCallback.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/IBluetoothPbap.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/IBluetoothPbapClient.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/IBluetoothPreferredAudioProfilesCallback.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/IBluetoothProfileServiceConnection.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/IBluetoothQualityReportReadyCallback.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/IBluetoothSap.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/IBluetoothSocketManager.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/IBluetoothVolumeControlCallback.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/IDistanceMeasurement.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/IncomingRfcommSocketInfo.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/OobData.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/le/AdvertiseData.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/le/AdvertiseSettings.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/le/AdvertisingSetParameters.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/le/DistanceMeasurementMethod.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/le/DistanceMeasurementParams.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/le/DistanceMeasurementResult.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/le/IAdvertisingSetCallback.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/le/IDistanceMeasurementCallback.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/le/IPeriodicAdvertisingCallback.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/le/IScannerCallback.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/le/PeriodicAdvertisingParameters.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/le/PeriodicAdvertisingReport.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/le/ResultStorageDescriptor.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/le/ScanFilter.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/le/ScanResult.aidl2
-rw-r--r--android/app/aidl/android/bluetooth/le/ScanSettings.aidl2
-rw-r--r--android/app/jni/com_android_bluetooth_BluetoothHciVendorSpecific.cpp2
-rw-r--r--android/app/jni/com_android_bluetooth_BluetoothQualityReport.cpp2
-rw-r--r--android/app/jni/com_android_bluetooth_btservice_BluetoothKeystore.cpp2
-rw-r--r--android/app/jni/com_android_bluetooth_gatt.cpp6
-rw-r--r--android/app/jni/com_android_bluetooth_hearing_aid.cpp2
-rw-r--r--android/app/jni/com_android_bluetooth_hfp.cpp7
-rw-r--r--android/app/lib-lint-baseline.xml995
-rw-r--r--android/app/lint-baseline.xml38
-rw-r--r--android/app/src/com/android/bluetooth/BluetoothEventLogger.java2
-rw-r--r--android/app/src/com/android/bluetooth/BluetoothMethodProxy.java7
-rw-r--r--android/app/src/com/android/bluetooth/Utils.java80
-rw-r--r--android/app/src/com/android/bluetooth/a2dp/A2dpCodecConfig.java2
-rw-r--r--android/app/src/com/android/bluetooth/a2dp/A2dpNativeCallback.java2
-rw-r--r--android/app/src/com/android/bluetooth/a2dp/A2dpNativeInterface.java2
-rw-r--r--android/app/src/com/android/bluetooth/a2dp/A2dpService.java339
-rw-r--r--android/app/src/com/android/bluetooth/a2dp/A2dpServiceBinder.java336
-rw-r--r--android/app/src/com/android/bluetooth/a2dp/A2dpStackEvent.java2
-rw-r--r--android/app/src/com/android/bluetooth/a2dp/A2dpStateMachine.java6
-rw-r--r--android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkService.java139
-rw-r--r--android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkServiceBinder.java157
-rw-r--r--android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkStateMachine.java4
-rw-r--r--android/app/src/com/android/bluetooth/audio_util/BrowsablePlayerConnector.java2
-rw-r--r--android/app/src/com/android/bluetooth/audio_util/BrowsedPlayerWrapper.java2
-rw-r--r--android/app/src/com/android/bluetooth/audio_util/GPMWrapper.java2
-rw-r--r--android/app/src/com/android/bluetooth/audio_util/MediaBrowserWrapper.java4
-rw-r--r--android/app/src/com/android/bluetooth/audio_util/MediaPlayerList.java2
-rw-r--r--android/app/src/com/android/bluetooth/audio_util/MediaPlayerWrapper.java2
-rw-r--r--android/app/src/com/android/bluetooth/audio_util/PlayerSettingsManager.java2
-rw-r--r--android/app/src/com/android/bluetooth/audio_util/helpers/PlayStatus.java2
-rw-r--r--android/app/src/com/android/bluetooth/audio_util/helpers/PlayerInfo.java2
-rw-r--r--android/app/src/com/android/bluetooth/audio_util/mockable/MediaBrowser.java2
-rw-r--r--android/app/src/com/android/bluetooth/audio_util/mockable/MediaBrowserFactory.java2
-rw-r--r--android/app/src/com/android/bluetooth/audio_util/mockable/MediaController.java2
-rw-r--r--android/app/src/com/android/bluetooth/audio_util/mockable/MediaControllerFactory.java2
-rw-r--r--android/app/src/com/android/bluetooth/audio_util/mockable/MediaPlayerWrapperFactory.java2
-rw-r--r--android/app/src/com/android/bluetooth/avrcp/AvrcpBipObexServer.java2
-rw-r--r--android/app/src/com/android/bluetooth/avrcp/AvrcpCoverArtService.java2
-rw-r--r--android/app/src/com/android/bluetooth/avrcp/AvrcpCoverArtStorage.java2
-rw-r--r--android/app/src/com/android/bluetooth/avrcp/AvrcpNativeInterface.java2
-rw-r--r--android/app/src/com/android/bluetooth/avrcp/AvrcpTargetService.java5
-rw-r--r--android/app/src/com/android/bluetooth/avrcp/AvrcpVolumeManager.java9
-rw-r--r--android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerNativeInterface.java2
-rw-r--r--android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerService.java90
-rw-r--r--android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerServiceBinder.java116
-rw-r--r--android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerStateMachine.java7
-rw-r--r--android/app/src/com/android/bluetooth/avrcpcontroller/bip/ParseException.java2
-rw-r--r--android/app/src/com/android/bluetooth/bas/BatteryService.java2
-rw-r--r--android/app/src/com/android/bluetooth/bas/BatteryStateMachine.java2
-rw-r--r--android/app/src/com/android/bluetooth/bass_client/BaseData.java2
-rw-r--r--android/app/src/com/android/bluetooth/bass_client/BassClientPeriodicAdvertisingManager.java2
-rw-r--r--android/app/src/com/android/bluetooth/bass_client/BassClientService.java320
-rw-r--r--android/app/src/com/android/bluetooth/bass_client/BassClientServiceBinder.java268
-rw-r--r--android/app/src/com/android/bluetooth/bass_client/BassClientStateMachine.java11
-rw-r--r--android/app/src/com/android/bluetooth/bass_client/BassConstants.java2
-rw-r--r--android/app/src/com/android/bluetooth/bass_client/BassUtils.java2
-rw-r--r--android/app/src/com/android/bluetooth/bass_client/PeriodicAdvertisementResult.java2
-rw-r--r--android/app/src/com/android/bluetooth/bass_client/PublicBroadcastData.java2
-rw-r--r--android/app/src/com/android/bluetooth/btservice/AdapterNativeInterface.java2
-rw-r--r--android/app/src/com/android/bluetooth/btservice/AdapterProperties.java3
-rw-r--r--android/app/src/com/android/bluetooth/btservice/AdapterService.java2485
-rw-r--r--android/app/src/com/android/bluetooth/btservice/AdapterServiceBinder.java2262
-rw-r--r--android/app/src/com/android/bluetooth/btservice/AdapterSuspend.java2
-rw-r--r--android/app/src/com/android/bluetooth/btservice/BluetoothAdapterProxy.java2
-rw-r--r--android/app/src/com/android/bluetooth/btservice/BluetoothHciVendorSpecificDispatcher.java2
-rw-r--r--android/app/src/com/android/bluetooth/btservice/BluetoothHciVendorSpecificNativeInterface.java2
-rw-r--r--android/app/src/com/android/bluetooth/btservice/BluetoothQualityReportNativeInterface.java2
-rw-r--r--android/app/src/com/android/bluetooth/btservice/BluetoothSocketManagerBinder.java4
-rw-r--r--android/app/src/com/android/bluetooth/btservice/Config.java9
-rw-r--r--android/app/src/com/android/bluetooth/btservice/DiscoveringPackage.java2
-rw-r--r--android/app/src/com/android/bluetooth/btservice/MetricsLogger.java149
-rw-r--r--android/app/src/com/android/bluetooth/btservice/ProfileService.java12
-rw-r--r--android/app/src/com/android/bluetooth/btservice/RemoteDevices.java121
-rw-r--r--android/app/src/com/android/bluetooth/btservice/SilenceDeviceManager.java4
-rw-r--r--android/app/src/com/android/bluetooth/btservice/bluetoothKeystore/BluetoothKeystoreNativeInterface.java2
-rw-r--r--android/app/src/com/android/bluetooth/btservice/bluetoothKeystore/BluetoothKeystoreService.java2
-rw-r--r--android/app/src/com/android/bluetooth/btservice/storage/AudioPolicyEntity.java2
-rw-r--r--android/app/src/com/android/bluetooth/btservice/storage/BluetoothDatabaseMigration.java2
-rw-r--r--android/app/src/com/android/bluetooth/btservice/storage/CustomizedMetadataEntity.java2
-rw-r--r--android/app/src/com/android/bluetooth/btservice/storage/DatabaseManager.java2
-rw-r--r--android/app/src/com/android/bluetooth/btservice/storage/Metadata.java2
-rw-r--r--android/app/src/com/android/bluetooth/btservice/storage/MetadataDao.java2
-rw-r--r--android/app/src/com/android/bluetooth/btservice/storage/MetadataDatabase.java2
-rw-r--r--android/app/src/com/android/bluetooth/btservice/storage/ProfilePrioritiesEntity.java2
-rw-r--r--android/app/src/com/android/bluetooth/content_profiles/ContentProfileErrorReportUtils.java2
-rw-r--r--android/app/src/com/android/bluetooth/csip/CsipSetCoordinatorService.java170
-rw-r--r--android/app/src/com/android/bluetooth/csip/CsipSetCoordinatorServiceBinder.java194
-rw-r--r--android/app/src/com/android/bluetooth/gatt/AdvertiseBinder.kt2
-rw-r--r--android/app/src/com/android/bluetooth/gatt/AppAdvertiseStats.java51
-rw-r--r--android/app/src/com/android/bluetooth/gatt/DistanceMeasurementBinder.kt3
-rw-r--r--android/app/src/com/android/bluetooth/gatt/DistanceMeasurementManager.java2
-rw-r--r--android/app/src/com/android/bluetooth/gatt/DistanceMeasurementNativeInterface.java2
-rw-r--r--android/app/src/com/android/bluetooth/gatt/DistanceMeasurementTracker.java2
-rw-r--r--android/app/src/com/android/bluetooth/gatt/GattNativeInterface.java2
-rw-r--r--android/app/src/com/android/bluetooth/gatt/GattObjectsFactory.java2
-rw-r--r--android/app/src/com/android/bluetooth/gatt/GattService.java632
-rw-r--r--android/app/src/com/android/bluetooth/gatt/GattServiceBinder.java499
-rw-r--r--android/app/src/com/android/bluetooth/gatt/HandleMap.java153
-rw-r--r--android/app/src/com/android/bluetooth/hap/HapClientNativeCallback.java2
-rw-r--r--android/app/src/com/android/bluetooth/hap/HapClientService.java2
-rw-r--r--android/app/src/com/android/bluetooth/hap/HapClientServiceBinder.java (renamed from android/app/src/com/android/bluetooth/hap/HapClientBinder.java)33
-rw-r--r--android/app/src/com/android/bluetooth/hearingaid/HearingAidNativeInterface.java2
-rw-r--r--android/app/src/com/android/bluetooth/hearingaid/HearingAidService.java227
-rw-r--r--android/app/src/com/android/bluetooth/hearingaid/HearingAidServiceBinder.java230
-rw-r--r--android/app/src/com/android/bluetooth/hearingaid/HearingAidStackEvent.java2
-rw-r--r--android/app/src/com/android/bluetooth/hearingaid/HearingAidStateMachine.java2
-rw-r--r--android/app/src/com/android/bluetooth/hfp/HeadsetAgIndicatorEnableState.java2
-rw-r--r--android/app/src/com/android/bluetooth/hfp/HeadsetCallState.java2
-rw-r--r--android/app/src/com/android/bluetooth/hfp/HeadsetClccResponse.java2
-rw-r--r--android/app/src/com/android/bluetooth/hfp/HeadsetDeviceState.java2
-rw-r--r--android/app/src/com/android/bluetooth/hfp/HeadsetMessageObject.java2
-rw-r--r--android/app/src/com/android/bluetooth/hfp/HeadsetNativeInterface.java70
-rw-r--r--android/app/src/com/android/bluetooth/hfp/HeadsetObjectsFactory.java2
-rw-r--r--android/app/src/com/android/bluetooth/hfp/HeadsetService.java319
-rw-r--r--android/app/src/com/android/bluetooth/hfp/HeadsetServiceBinder.java319
-rw-r--r--android/app/src/com/android/bluetooth/hfp/HeadsetStackEvent.java2
-rw-r--r--android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java6
-rw-r--r--android/app/src/com/android/bluetooth/hfp/HeadsetSystemInterface.java3
-rw-r--r--android/app/src/com/android/bluetooth/hfp/HeadsetVendorSpecificResultCode.java2
-rw-r--r--android/app/src/com/android/bluetooth/hfpclient/HeadsetClientService.java344
-rw-r--r--android/app/src/com/android/bluetooth/hfpclient/HeadsetClientServiceBinder.java345
-rw-r--r--android/app/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java3
-rw-r--r--android/app/src/com/android/bluetooth/hfpclient/VendorCommandResponseProcessor.java2
-rw-r--r--android/app/src/com/android/bluetooth/hid/HidDeviceNativeInterface.java2
-rw-r--r--android/app/src/com/android/bluetooth/hid/HidDeviceService.java207
-rw-r--r--android/app/src/com/android/bluetooth/hid/HidDeviceServiceBinder.java218
-rw-r--r--android/app/src/com/android/bluetooth/hid/HidHostNativeInterface.java2
-rw-r--r--android/app/src/com/android/bluetooth/hid/HidHostService.java225
-rw-r--r--android/app/src/com/android/bluetooth/hid/HidHostServiceBinder.java232
-rw-r--r--android/app/src/com/android/bluetooth/le_audio/LeAudioService.java697
-rw-r--r--android/app/src/com/android/bluetooth/le_audio/LeAudioServiceBinder.java548
-rw-r--r--android/app/src/com/android/bluetooth/le_audio/LeAudioTmapGattServer.java2
-rw-r--r--android/app/src/com/android/bluetooth/le_scan/AppScanStats.java249
-rw-r--r--android/app/src/com/android/bluetooth/le_scan/BatchScanThrottler.java2
-rw-r--r--android/app/src/com/android/bluetooth/le_scan/PeriodicScanNativeInterface.java2
-rw-r--r--android/app/src/com/android/bluetooth/le_scan/ScanBinder.java182
-rw-r--r--android/app/src/com/android/bluetooth/le_scan/ScanBinder.kt150
-rw-r--r--android/app/src/com/android/bluetooth/le_scan/ScanController.java71
-rw-r--r--android/app/src/com/android/bluetooth/le_scan/ScanManager.java12
-rw-r--r--android/app/src/com/android/bluetooth/le_scan/ScanObjectsFactory.java2
-rw-r--r--android/app/src/com/android/bluetooth/map/BluetoothMapAppParams.java25
-rw-r--r--android/app/src/com/android/bluetooth/map/BluetoothMapConvoContactElement.java5
-rw-r--r--android/app/src/com/android/bluetooth/map/BluetoothMapConvoListingElement.java5
-rw-r--r--android/app/src/com/android/bluetooth/map/BluetoothMapMessageListingElement.java3
-rw-r--r--android/app/src/com/android/bluetooth/map/BluetoothMapService.java234
-rw-r--r--android/app/src/com/android/bluetooth/map/BluetoothMapServiceBinder.java251
-rw-r--r--android/app/src/com/android/bluetooth/map/BluetoothMapSmsPdu.java7
-rw-r--r--android/app/src/com/android/bluetooth/map/BluetoothMapUtils.java4
-rw-r--r--android/app/src/com/android/bluetooth/mapclient/MapClientService.java177
-rw-r--r--android/app/src/com/android/bluetooth/mapclient/MapClientServiceBinder.java193
-rw-r--r--android/app/src/com/android/bluetooth/mapclient/MceStateMachine.java4
-rw-r--r--android/app/src/com/android/bluetooth/mcp/GattOpContext.java48
-rw-r--r--android/app/src/com/android/bluetooth/mcp/McpService.java42
-rw-r--r--android/app/src/com/android/bluetooth/mcp/McpServiceBinder.java63
-rw-r--r--android/app/src/com/android/bluetooth/mcp/MediaControlGattService.java205
-rw-r--r--android/app/src/com/android/bluetooth/notification/NotificationHelperService.java2
-rw-r--r--android/app/src/com/android/bluetooth/opp/BluetoothOppLauncherActivity.java15
-rw-r--r--android/app/src/com/android/bluetooth/opp/BluetoothOppObexClientSession.java9
-rw-r--r--android/app/src/com/android/bluetooth/opp/BluetoothOppObexServerSession.java8
-rw-r--r--android/app/src/com/android/bluetooth/opp/BluetoothOppReceiveFileInfo.java3
-rw-r--r--android/app/src/com/android/bluetooth/opp/BluetoothOppUtility.java31
-rw-r--r--android/app/src/com/android/bluetooth/pan/PanNativeInterface.java2
-rw-r--r--android/app/src/com/android/bluetooth/pan/PanService.java145
-rw-r--r--android/app/src/com/android/bluetooth/pan/PanServiceBinder.java161
-rw-r--r--android/app/src/com/android/bluetooth/pbap/BluetoothPbapActivity.java2
-rw-r--r--android/app/src/com/android/bluetooth/pbap/BluetoothPbapAuthenticator.java2
-rw-r--r--android/app/src/com/android/bluetooth/pbap/BluetoothPbapCallLogComposer.java3
-rw-r--r--android/app/src/com/android/bluetooth/pbap/BluetoothPbapConfig.java2
-rw-r--r--android/app/src/com/android/bluetooth/pbap/BluetoothPbapObexServer.java2
-rw-r--r--android/app/src/com/android/bluetooth/pbap/BluetoothPbapService.java104
-rw-r--r--android/app/src/com/android/bluetooth/pbap/BluetoothPbapServiceBinder.java121
-rw-r--r--android/app/src/com/android/bluetooth/pbap/BluetoothPbapSimVcardManager.java2
-rw-r--r--android/app/src/com/android/bluetooth/pbap/BluetoothPbapUtils.java2
-rw-r--r--android/app/src/com/android/bluetooth/pbap/BluetoothPbapVcardManager.java2
-rw-r--r--android/app/src/com/android/bluetooth/pbap/HandlerForStringBuffer.java2
-rw-r--r--android/app/src/com/android/bluetooth/pbap/PbapStateMachine.java5
-rw-r--r--android/app/src/com/android/bluetooth/pbapclient/PbapClientContactsStorage.java3
-rw-r--r--android/app/src/com/android/bluetooth/pbapclient/PbapClientService.java2
-rw-r--r--android/app/src/com/android/bluetooth/pbapclient/PbapClientServiceBinder.java (renamed from android/app/src/com/android/bluetooth/pbapclient/PbapClientBinder.java)6
-rw-r--r--android/app/src/com/android/bluetooth/pbapclient/PbapClientStateMachine.java4
-rw-r--r--android/app/src/com/android/bluetooth/pbapclient/PbapClientStateMachineOld.java4
-rw-r--r--android/app/src/com/android/bluetooth/pbapclient/obex/CallLogPullRequest.java3
-rw-r--r--android/app/src/com/android/bluetooth/sap/SapService.java157
-rw-r--r--android/app/src/com/android/bluetooth/sap/SapServiceBinder.java166
-rw-r--r--android/app/src/com/android/bluetooth/sdp/SdpManagerNativeInterface.java2
-rw-r--r--android/app/src/com/android/bluetooth/tbs/TbsGatt.java177
-rw-r--r--android/app/src/com/android/bluetooth/tbs/TbsService.java114
-rw-r--r--android/app/src/com/android/bluetooth/tbs/TbsServiceBinder.java126
-rw-r--r--android/app/src/com/android/bluetooth/util/SystemProperties.java2
-rw-r--r--android/app/src/com/android/bluetooth/vc/VolumeControlNativeCallback.java2
-rw-r--r--android/app/src/com/android/bluetooth/vc/VolumeControlService.java522
-rw-r--r--android/app/src/com/android/bluetooth/vc/VolumeControlServiceBinder.java528
-rw-r--r--android/app/tests/instrumentation/com/android/bluetooth/opp/BluetoothOppLauncherActivityTest.java25
-rw-r--r--android/app/tests/unit/Android.bp9
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/ObexAppParametersTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/SignedLongLongTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/TestUtils.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/UtilsTest.java11
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/a2dp/A2dpCodecConfigTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/a2dp/A2dpServiceBinderTest.java18
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/a2dp/A2dpServiceTest.java37
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/a2dp/A2dpStateMachineTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/a2dpsink/A2dpSinkServiceBinderTest.java14
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/a2dpsink/A2dpSinkServiceTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/a2dpsink/A2dpSinkStateMachineTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/a2dpsink/StackEventTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/audio_util/BrowsablePlayerConnectorTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/audio_util/BrowserPlayerWrapperTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/audio_util/GPMWrapperTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/audio_util/ImageTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/audio_util/MediaPlayerListTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/audio_util/MediaPlayerWrapperTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/audio_util/MetadataTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/audio_util/UtilTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/avrcp/AvrcpBipObexServerTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/avrcp/AvrcpCoverArtStorageTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/avrcp/AvrcpTargetServiceTest.java4
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/avrcp/AvrcpVolumeManagerTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/avrcp/CoverArtTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpBipClientTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerNativeInterfaceTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerServiceBinderTest.java12
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerServiceTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerStateMachineTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtProviderTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtStorageTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpItemTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpPlayerTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/BrowseNodeTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/BrowseTreeTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/PlayerApplicationSettingsTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/StackEventTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipAttachmentFormatTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipDatetimeTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipEncodingTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipImageDescriptorTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipImageFormatTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipImagePropertiesTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipImageTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipPixelTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipTransformationTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/RequestGetImagePropertiesTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/RequestGetImageTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/bas/BatteryServiceTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/bas/BatteryStateMachineTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/bass_client/BaseDataTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/bass_client/BassClientServiceBinderTest.java (renamed from android/app/tests/unit/src/com/android/bluetooth/bass_client/BleBroadcastAssistantBinderTest.java)16
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/bass_client/BassClientServiceTest.java126
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/bass_client/BassClientStateMachineTest.java4
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/bass_client/PeriodicAdvertisementResultTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/bass_client/PublicBroadcastDataTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/btservice/ActiveDeviceManagerTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterPropertiesTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceBinderTest.java20
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceTest.java3
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterSuspendTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/btservice/BondStateMachineTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/btservice/CompanionManagerTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/btservice/ConfigTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/btservice/MetricsLoggerTest.java119
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/btservice/ProfileServiceTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/btservice/SilenceDeviceManagerTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/btservice/bluetoothKeystore/BluetoothKeystoreServiceTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/btservice/storage/AudioPolicyEntityTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/btservice/storage/DatabaseManagerTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/content_profiles/ContentProfileErrorReportUtilsTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/csip/CsipSetCoordinatorServiceBinderTest.java (renamed from android/app/tests/unit/src/com/android/bluetooth/csip/BluetoothCsisBinderTest.java)21
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/csip/CsipSetCoordinatorServiceTest.java1
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/gatt/AdvertiseBinderTest.java202
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/gatt/AdvertiseBinderTest.kt201
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/gatt/AdvertiseHelperTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/gatt/AdvertiseManagerTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/gatt/AdvertiserMapTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/gatt/AppAdvertiseStatsTest.java9
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/gatt/ContextMapTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/gatt/DistanceMeasurementBinderTest.java119
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/gatt/DistanceMeasurementBinderTest.kt112
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/gatt/GattDebugUtilsTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/gatt/GattServiceBinderTest.java44
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/gatt/GattServiceTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/hap/HapClientNativeCallbackTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/hap/HapClientServiceBinderTest.java (renamed from android/app/tests/unit/src/com/android/bluetooth/hap/HapClientBinderTest.java)9
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/hap/HapClientStackEventTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/hearingaid/HearingAidNativeInterfaceTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/hearingaid/HearingAidServiceBinderTest.java200
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/hearingaid/HearingAidServiceTest.java6
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/hearingaid/HearingAidStateMachineTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/hfp/AtPhonebookTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetAgIndicatorEnableStateTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetClccResponseTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetPhoneStateTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetServiceAndStateMachineTest.java13
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetServiceBinderTest.java (renamed from android/app/tests/unit/src/com/android/bluetooth/hfp/BluetoothHeadsetBinderTest.java)19
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetServiceTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetStackEventTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetStateMachineTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetTestUtils.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetVendorSpecificResultCodeTest.java2
-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.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachineTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/hfpclient/HfpNativeInterfaceTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/hfpclient/StackEventTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/hfpclient/VendorCommandResponseProcessorTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/hid/HidDeviceNativeInterfaceTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/hid/HidDeviceServiceBinderTest.java (renamed from android/app/tests/unit/src/com/android/bluetooth/hid/BluetoothHidDeviceBinderTest.java)16
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/hid/HidDeviceServiceTest.java (renamed from android/app/tests/unit/src/com/android/bluetooth/hid/HidDeviceTest.java)4
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/hid/HidHostServiceBinderTest.java33
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/hid/HidHostServiceTest.java4
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioBroadcastServiceTest.java57
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioBroadcasterNativeInterfaceTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioNativeInterfaceTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioServiceBinderTest.java (renamed from android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioBinderTest.java)16
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioServiceTest.java106
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/le_scan/AdvtFilterOnFoundOnLostInfoTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/le_scan/AppScanStatsTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/le_scan/ScanBinderTest.kt187
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/le_scan/ScanControllerTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/le_scan/ScanFilterQueueTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/le_scan/ScanManagerTest.java35
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/le_scan/ScannerMapTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapAccountItemTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapAppParamsTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapContentObserverTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapContentTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapConvoContactElementTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapConvoListingElementTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapConvoListingTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapMasInstanceTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapMessageListingElementTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapMessageListingTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapObexServerTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapServiceBinderTest.java20
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapServiceTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapSmsPduTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapUtilsTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapbMessageEmailTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapbMessageSmsTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapbMessageTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapbMessageVCardTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/map/ConvoContactInfoTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/map/EventTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/map/FilterInfoTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/map/MapContactTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/map/MsgTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/map/SmsMmsContactsTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/mapapi/BluetoothMapContractTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/mapapi/BluetoothMapEmailProviderTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/mapapi/BluetoothMapIMProviderTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/mapclient/EventReportTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/mapclient/MapClientServiceBinderTest.java21
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/mapclient/MapClientServiceTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/mapclient/MessageTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/mapclient/MessagesFilterTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/mapclient/MessagesListingTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/mapclient/MnsObexServerTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/mapclient/RequestGetMessagesListingForOwnNumberTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/mcp/McpServiceBinderTest.java69
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppBatchTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppHandoverReceiverTest.java2
-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.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppObexClientSessionTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppObexServerSessionTest.java2
-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/BluetoothOppReceiveFileInfoTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppReceiverTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppSendFileInfoTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppServiceTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppShareInfoTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppTestUtils.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppTransferActivityTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppTransferTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppUtilityTest.java21
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/pan/BluetoothTetheringNetworkFactoryTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/pan/PanServiceBinderTest.java19
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/pan/PanServiceTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapCallLogComposerTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapConfigTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapObexServerTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapServiceBinderTest.java8
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapServiceTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapSimVcardManagerTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapUtilsTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapVcardManagerNestedClassesTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapVcardManagerTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/pbap/HandlerForStringBufferTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/pbap/PbapStateMachineTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/pbapclient/CallLogPullRequestTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/pbapclient/FakeContactsProvider.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapApplicationParametersTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientAccountAuthenticatorServiceTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientAccountAuthenticatorTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientAccountManagerTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientConnectionHandlerTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientContactsStorageTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientObexAuthenticatorTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientObexClientTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientObexTransportTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientServiceBinderTest.java (renamed from android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientBinderTest.java)58
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientServiceTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientSocketTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientStateMachineOldTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientStateMachineTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapPhonebookMetadataTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapPhonebookTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapSdpRecordTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/pbapclient/PhonebookPullRequestTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/pbapclient/RequestPullPhonebookMetadataTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/pbapclient/RequestPullPhonebookTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/pbapclient/Utils.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/sap/SapMessageTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/sap/SapRilReceiverHidlTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/sap/SapRilReceiverTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/sap/SapServerTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/sap/SapServiceBinderTest.java132
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/sap/SapServiceTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/sdp/DipTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/tbs/TbsServiceBinderTest.java146
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/telephony/BluetoothCallTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlNativeCallbackTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlServiceBinderTest.java294
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlServiceTest.java4
-rw-r--r--android/leaudio/app/.classpath2
-rw-r--r--android/leaudio/gradle/wrapper/gradle-wrapper.jarbin54329 -> 59821 bytes
-rw-r--r--android/leaudio/gradle/wrapper/gradle-wrapper.properties3
-rwxr-xr-xandroid/leaudio/gradlew282
-rw-r--r--android/leaudio/gradlew.bat43
-rw-r--r--android/pandora/server/configs/pts_bot_tests_config.json4
-rw-r--r--android/pandora/test/main.py2
-rw-r--r--android/pandora/test/rfcomm_test.py110
-rw-r--r--apex/Android.bp1
-rw-r--r--flags/a2dp.aconfig30
-rw-r--r--flags/gap.aconfig24
-rw-r--r--flags/hci.aconfig7
-rw-r--r--flags/hid.aconfig10
-rw-r--r--flags/l2cap.aconfig10
-rw-r--r--flags/leaudio.aconfig10
-rw-r--r--flags/opp.aconfig17
-rw-r--r--flags/pairing.aconfig30
-rw-r--r--flags/security.aconfig17
-rw-r--r--flags/sockets.aconfig10
-rw-r--r--flags/system_service.aconfig10
-rw-r--r--framework/Android.bp1
-rw-r--r--framework/api/system-current.txt3
-rw-r--r--framework/java/android/bluetooth/BluetoothAdapter.java3
-rw-r--r--framework/java/android/bluetooth/BluetoothDevice.java35
-rw-r--r--framework/java/android/bluetooth/BluetoothDevicePicker.java11
-rw-r--r--framework/java/android/bluetooth/BluetoothHearingAid.java2
-rw-r--r--framework/java/android/bluetooth/BluetoothLeBroadcast.java2
-rw-r--r--framework/java/android/bluetooth/BluetoothLeBroadcastAssistant.java2
-rw-r--r--framework/java/android/bluetooth/BluetoothLeBroadcastChannel.java2
-rw-r--r--framework/java/android/bluetooth/BluetoothLeBroadcastMetadata.java2
-rw-r--r--framework/java/android/bluetooth/BluetoothLeBroadcastReceiveState.java2
-rw-r--r--framework/java/android/bluetooth/BluetoothLeBroadcastSettings.java2
-rw-r--r--framework/java/android/bluetooth/BluetoothLeBroadcastSubgroup.java2
-rw-r--r--framework/java/android/bluetooth/BluetoothLeBroadcastSubgroupSettings.java2
-rw-r--r--framework/java/android/bluetooth/BluetoothSinkAudioPolicy.java2
-rw-r--r--framework/java/android/bluetooth/BluetoothSocketSettings.java2
-rw-r--r--framework/java/android/bluetooth/le/ChannelSoundingParams.java2
-rw-r--r--framework/java/android/bluetooth/le/DistanceMeasurementManager.java13
-rw-r--r--framework/java/android/bluetooth/le/DistanceMeasurementMethod.java2
-rw-r--r--framework/java/android/bluetooth/le/DistanceMeasurementParams.java2
-rw-r--r--framework/java/android/bluetooth/le/DistanceMeasurementResult.java2
-rw-r--r--framework/java/android/bluetooth/le/DistanceMeasurementSession.java2
-rw-r--r--framework/java/android/bluetooth/le/TransportBlockFilter.java2
-rw-r--r--framework/tests/bumble/src/android/bluetooth/pairing/OobPairingTest.java9
-rw-r--r--framework/tests/unit/src/android/bluetooth/BluetoothActivityEnergyInfoTest.java2
-rw-r--r--framework/tests/unit/src/android/bluetooth/BluetoothAudioConfigTest.java2
-rw-r--r--framework/tests/unit/src/android/bluetooth/BluetoothCodecConfigTest.java2
-rw-r--r--framework/tests/unit/src/android/bluetooth/BluetoothCodecStatusTest.java2
-rw-r--r--framework/tests/unit/src/android/bluetooth/BluetoothDeviceTest.java2
-rw-r--r--framework/tests/unit/src/android/bluetooth/CallbackWrapperTest.java2
-rw-r--r--framework/tests/unit/src/android/bluetooth/SdpDipRecordTest.java2
-rw-r--r--framework/tests/unit/src/android/bluetooth/SdpMnsRecordTest.java2
-rw-r--r--framework/tests/unit/src/android/bluetooth/SdpOppOpsRecordTest.java2
-rw-r--r--framework/tests/unit/src/android/bluetooth/SdpPseRecordTest.java2
-rw-r--r--framework/tests/unit/src/android/bluetooth/SdpRecordTest.java2
-rw-r--r--framework/tests/unit/src/android/bluetooth/SdpSapsRecordTest.java2
-rw-r--r--offload/leaudio/hci/proxy.rs30
-rw-r--r--service/Android.bp17
-rwxr-xr-xservice/kls-classpath1
-rw-r--r--service/src/ActiveLog.kt16
-rw-r--r--service/src/ActiveLogTest.kt11
-rw-r--r--service/src/com/android/server/bluetooth/BluetoothManagerService.java439
-rw-r--r--service/tests/Android.bp1
-rw-r--r--service/tests/src/com/android/server/bluetooth/BluetoothManagerServiceTest.java304
-rw-r--r--system/BUILD.gn1
-rw-r--r--system/audio_hal_interface/aidl/le_audio_software_aidl.cc26
-rw-r--r--system/bta/Android.bp4
-rw-r--r--system/bta/BUILD.gn1
-rw-r--r--system/bta/gatt/bta_gattc_utils.cc2
-rw-r--r--system/bta/le_audio/broadcaster/broadcaster_test.cc9
-rw-r--r--system/bta/le_audio/codec_manager.cc10
-rw-r--r--system/bta/le_audio/codec_manager_test.cc26
-rw-r--r--system/bta/le_audio/devices_test.cc7
-rw-r--r--system/bta/le_audio/le_audio_client_test.cc13
-rw-r--r--system/bta/le_audio/state_machine_test.cc7
-rw-r--r--system/bta/test/bta_ag_sco_test.cc6
-rw-r--r--system/bta/test/bta_ag_test.cc6
-rw-r--r--system/bta/test/bta_dm_test.cc11
-rw-r--r--system/bta/test/bta_sdp_test.cc11
-rw-r--r--system/bta/test/bta_test_fixtures.h6
-rw-r--r--system/btif/Android.bp1
-rw-r--r--system/btif/BUILD.gn1
-rw-r--r--system/btif/include/btif_metrics_logging.h69
-rw-r--r--system/btif/include/btif_sock_logging.h4
-rw-r--r--system/btif/src/bluetooth.cc4
-rw-r--r--system/btif/src/btif_a2dp_source.cc127
-rw-r--r--system/btif/src/btif_av.cc41
-rw-r--r--system/btif/src/btif_config.cc15
-rw-r--r--system/btif/src/btif_dm.cc19
-rw-r--r--system/btif/src/btif_hf.cc23
-rw-r--r--system/btif/src/btif_hh.cc26
-rw-r--r--system/btif/src/btif_metrics_logging.cc107
-rw-r--r--system/btif/src/btif_sock.cc15
-rw-r--r--system/btif/src/btif_sock_l2cap.cc118
-rw-r--r--system/btif/src/btif_sock_logging.cc68
-rw-r--r--system/btif/src/btif_sock_rfc.cc99
-rw-r--r--system/btif/test/btif_core_test.cc27
-rw-r--r--system/common/Android.bp2
-rw-r--r--system/common/BUILD.gn1
-rw-r--r--system/common/id_generator.h48
-rw-r--r--system/common/id_generator_unittest.cc37
-rw-r--r--system/common/lru.h187
-rw-r--r--system/common/lru_unittest.cc250
-rw-r--r--system/common/metrics.cc333
-rw-r--r--system/common/metrics.h202
-rw-r--r--system/common/metrics_linux.cc65
-rw-r--r--system/conf/interop_database.conf5
-rw-r--r--system/device/include/interop.h10
-rw-r--r--system/device/src/interop.cc1
-rw-r--r--system/gd/Android.bp8
-rw-r--r--system/gd/AndroidTestTemplate.xml2
-rw-r--r--system/gd/benchmark.cc2
-rw-r--r--system/gd/common/audit_log.cc2
-rw-r--r--system/gd/common/audit_log.h2
-rw-r--r--system/gd/common/bidi_queue.h2
-rw-r--r--system/gd/common/bidi_queue_unittest.cc2
-rw-r--r--system/gd/common/bind.h2
-rw-r--r--system/gd/common/blocking_queue.h2
-rw-r--r--system/gd/common/blocking_queue_unittest.cc2
-rw-r--r--system/gd/common/byte_array.h2
-rw-r--r--system/gd/common/byte_array_test.cc2
-rw-r--r--system/gd/common/callback.h2
-rw-r--r--system/gd/common/circular_buffer.h2
-rw-r--r--system/gd/common/circular_buffer_test.cc2
-rw-r--r--system/gd/common/contextual_callback.h2
-rw-r--r--system/gd/common/i_postable_context.h2
-rw-r--r--system/gd/common/list_map.h2
-rw-r--r--system/gd/common/list_map_test.cc2
-rw-r--r--system/gd/common/lru_cache.h2
-rw-r--r--system/gd/common/lru_cache_test.cc2
-rw-r--r--system/gd/common/multi_priority_queue.h2
-rw-r--r--system/gd/common/multi_priority_queue_test.cc2
-rw-r--r--system/gd/common/numbers.h2
-rw-r--r--system/gd/common/numbers_test.cc2
-rw-r--r--system/gd/common/postable_context.h2
-rw-r--r--system/gd/common/stop_watch.cc2
-rw-r--r--system/gd/common/stop_watch.h2
-rw-r--r--system/gd/common/strings.cc2
-rw-r--r--system/gd/common/strings.h2
-rw-r--r--system/gd/common/strings_test.cc2
-rw-r--r--system/gd/common/sync_map_count.h2
-rw-r--r--system/gd/common/sync_map_count_test.cc2
-rw-r--r--system/gd/common/testing/bind_test_util.h2
-rw-r--r--system/gd/common/testing/wired_pair_of_bidi_queues.h2
-rw-r--r--system/gd/common/type_helper.h2
-rw-r--r--system/gd/crypto_toolbox/crypto_toolbox_test.cc2
-rw-r--r--system/gd/fuzz/helpers.cc2
-rw-r--r--system/gd/fuzz/helpers.h2
-rw-r--r--system/gd/fuzz_test.cc2
-rw-r--r--system/gd/hal/fuzz/fuzz_hci_hal.cc2
-rw-r--r--system/gd/hal/fuzz/fuzz_hci_hal.h2
-rw-r--r--system/gd/hal/hci_backend.h2
-rw-r--r--system/gd/hal/hci_backend_aidl.cc2
-rw-r--r--system/gd/hal/hci_backend_hidl.cc2
-rw-r--r--system/gd/hal/hci_hal.h9
-rw-r--r--system/gd/hal/hci_hal_android.cc2
-rw-r--r--system/gd/hal/hci_hal_android_test.cc10
-rw-r--r--system/gd/hal/hci_hal_fake.cc2
-rw-r--r--system/gd/hal/hci_hal_fake.h2
-rw-r--r--system/gd/hal/hci_hal_host.cc38
-rw-r--r--system/gd/hal/hci_hal_host.h2
-rw-r--r--system/gd/hal/hci_hal_host_rootcanal.cc2
-rw-r--r--system/gd/hal/hci_hal_host_test.cc10
-rw-r--r--system/gd/hal/link_clocker.cc2
-rw-r--r--system/gd/hal/link_clocker.h2
-rw-r--r--system/gd/hal/ranging_hal.h2
-rw-r--r--system/gd/hal/ranging_hal_android.cc2
-rw-r--r--system/gd/hal/ranging_hal_host.cc2
-rw-r--r--system/gd/hal/ranging_hal_mock.h2
-rw-r--r--system/gd/hal/serialize_packet.h2
-rw-r--r--system/gd/hal/snoop_logger.cc2
-rw-r--r--system/gd/hal/snoop_logger.h2
-rw-r--r--system/gd/hal/snoop_logger_socket_test.cc2
-rw-r--r--system/gd/hal/snoop_logger_socket_thread_test.cc2
-rw-r--r--system/gd/hal/snoop_logger_test.cc2
-rw-r--r--system/gd/hal/snoop_logger_tracing.cc2
-rw-r--r--system/gd/hal/snoop_logger_tracing.h2
-rw-r--r--system/gd/hal/socket_hal.h2
-rw-r--r--system/gd/hal/socket_hal_android.cc2
-rw-r--r--system/gd/hal/socket_hal_host.cc2
-rw-r--r--system/gd/hci/acl_builder_test.cc2
-rw-r--r--system/gd/hci/acl_connection_interface.h2
-rw-r--r--system/gd/hci/acl_manager.cc7
-rw-r--r--system/gd/hci/acl_manager.h3
-rw-r--r--system/gd/hci/acl_manager/acl_connection.cc2
-rw-r--r--system/gd/hci/acl_manager/acl_connection.h2
-rw-r--r--system/gd/hci/acl_manager/acl_fragmenter.cc2
-rw-r--r--system/gd/hci/acl_manager/acl_fragmenter.h2
-rw-r--r--system/gd/hci/acl_manager/acl_scheduler.cc2
-rw-r--r--system/gd/hci/acl_manager/acl_scheduler.h2
-rw-r--r--system/gd/hci/acl_manager/acl_scheduler_test.cc2
-rw-r--r--system/gd/hci/acl_manager/assembler.h2
-rw-r--r--system/gd/hci/acl_manager/classic_acl_connection.cc2
-rw-r--r--system/gd/hci/acl_manager/classic_acl_connection.h2
-rw-r--r--system/gd/hci/acl_manager/classic_acl_connection_test.cc2
-rw-r--r--system/gd/hci/acl_manager/classic_impl.h2
-rw-r--r--system/gd/hci/acl_manager/classic_impl_test.cc2
-rw-r--r--system/gd/hci/acl_manager/connection_callbacks.h2
-rw-r--r--system/gd/hci/acl_manager/connection_callbacks_mock.h2
-rw-r--r--system/gd/hci/acl_manager/connection_management_callbacks.h2
-rw-r--r--system/gd/hci/acl_manager/connection_management_callbacks_mock.h2
-rw-r--r--system/gd/hci/acl_manager/le_acceptlist_callbacks.h2
-rw-r--r--system/gd/hci/acl_manager/le_acl_connection.cc2
-rw-r--r--system/gd/hci/acl_manager/le_acl_connection.h2
-rw-r--r--system/gd/hci/acl_manager/le_acl_connection_test.cc2
-rw-r--r--system/gd/hci/acl_manager/le_connection_callbacks.h2
-rw-r--r--system/gd/hci/acl_manager/le_connection_callbacks_mock.h2
-rw-r--r--system/gd/hci/acl_manager/le_connection_management_callbacks.h2
-rw-r--r--system/gd/hci/acl_manager/le_connection_management_callbacks_mock.h2
-rw-r--r--system/gd/hci/acl_manager/le_impl.h26
-rw-r--r--system/gd/hci/acl_manager/le_impl_test.cc2
-rw-r--r--system/gd/hci/acl_manager/round_robin_scheduler.cc12
-rw-r--r--system/gd/hci/acl_manager/round_robin_scheduler.h2
-rw-r--r--system/gd/hci/acl_manager/round_robin_scheduler_test.cc5
-rw-r--r--system/gd/hci/acl_manager_mock.h2
-rw-r--r--system/gd/hci/acl_manager_test.cc2
-rw-r--r--system/gd/hci/acl_manager_unittest.cc2
-rw-r--r--system/gd/hci/address_unittest.cc2
-rw-r--r--system/gd/hci/address_with_type.h2
-rw-r--r--system/gd/hci/address_with_type_test.cc2
-rw-r--r--system/gd/hci/class_of_device_unittest.cc2
-rw-r--r--system/gd/hci/command_interface.h2
-rw-r--r--system/gd/hci/controller.cc6
-rw-r--r--system/gd/hci/controller.h2
-rw-r--r--system/gd/hci/controller_interface.h2
-rw-r--r--system/gd/hci/controller_interface_mock.h2
-rw-r--r--system/gd/hci/controller_mock.h2
-rw-r--r--system/gd/hci/controller_test.cc2
-rw-r--r--system/gd/hci/controller_unittest.cc2
-rw-r--r--system/gd/hci/distance_measurement_interface.h2
-rw-r--r--system/gd/hci/distance_measurement_manager.cc130
-rw-r--r--system/gd/hci/distance_measurement_manager.h2
-rw-r--r--system/gd/hci/distance_measurement_manager_mock.h12
-rw-r--r--system/gd/hci/distance_measurement_manager_test.cc534
-rw-r--r--system/gd/hci/enum_helper.h2
-rw-r--r--system/gd/hci/event_checkers.h2
-rw-r--r--system/gd/hci/fuzz/acl_manager_fuzz_test.cc2
-rw-r--r--system/gd/hci/fuzz/fuzz_hci_layer.cc2
-rw-r--r--system/gd/hci/fuzz/fuzz_hci_layer.h2
-rw-r--r--system/gd/hci/fuzz/hci_layer_fuzz_client.cc2
-rw-r--r--system/gd/hci/fuzz/hci_layer_fuzz_client.h2
-rw-r--r--system/gd/hci/fuzz/hci_layer_fuzz_test.cc2
-rw-r--r--system/gd/hci/fuzz/status_vs_complete_commands.cc2
-rw-r--r--system/gd/hci/fuzz/status_vs_complete_commands.h2
-rw-r--r--system/gd/hci/hci_interface.h2
-rw-r--r--system/gd/hci/hci_layer.cc43
-rw-r--r--system/gd/hci/hci_layer.h4
-rw-r--r--system/gd/hci/hci_layer_fake.cc2
-rw-r--r--system/gd/hci/hci_layer_fake.h2
-rw-r--r--system/gd/hci/hci_layer_mock.h2
-rw-r--r--system/gd/hci/hci_layer_test.cc2
-rw-r--r--system/gd/hci/hci_layer_unittest.cc2
-rw-r--r--system/gd/hci/hci_metrics_logging.cc2
-rw-r--r--system/gd/hci/hci_metrics_logging.h2
-rw-r--r--system/gd/hci/hci_packets_fuzz_test.cc2
-rw-r--r--system/gd/hci/hci_packets_test.cc2
-rw-r--r--system/gd/hci/inquiry_interface.h2
-rw-r--r--system/gd/hci/le_acl_connection_interface.h2
-rw-r--r--system/gd/hci/le_address_manager.cc60
-rw-r--r--system/gd/hci/le_address_manager.h2
-rw-r--r--system/gd/hci/le_address_manager_test.cc2
-rw-r--r--system/gd/hci/le_advertising_interface.h2
-rw-r--r--system/gd/hci/le_advertising_manager.cc173
-rw-r--r--system/gd/hci/le_advertising_manager.h2
-rw-r--r--system/gd/hci/le_advertising_manager_mock.h2
-rw-r--r--system/gd/hci/le_advertising_manager_test.cc2
-rw-r--r--system/gd/hci/le_iso_interface.h2
-rw-r--r--system/gd/hci/le_periodic_sync_manager.h2
-rw-r--r--system/gd/hci/le_periodic_sync_manager_test.cc2
-rw-r--r--system/gd/hci/le_rand_callback.h2
-rw-r--r--system/gd/hci/le_scanning_callback.h2
-rw-r--r--system/gd/hci/le_scanning_interface.h2
-rw-r--r--system/gd/hci/le_scanning_manager.cc2
-rw-r--r--system/gd/hci/le_scanning_manager.h2
-rw-r--r--system/gd/hci/le_scanning_manager_mock.h2
-rw-r--r--system/gd/hci/le_scanning_manager_test.cc2
-rw-r--r--system/gd/hci/le_scanning_reassembler.cc2
-rw-r--r--system/gd/hci/le_scanning_reassembler.h2
-rw-r--r--system/gd/hci/le_scanning_reassembler_test.cc2
-rw-r--r--system/gd/hci/le_security_interface.h2
-rw-r--r--system/gd/hci/link_key.cc2
-rw-r--r--system/gd/hci/link_key.h2
-rw-r--r--system/gd/hci/msft.cc2
-rw-r--r--system/gd/hci/msft.h2
-rw-r--r--system/gd/hci/octets.h2
-rw-r--r--system/gd/hci/remote_name_request.cc2
-rw-r--r--system/gd/hci/remote_name_request.h2
-rw-r--r--system/gd/hci/remote_name_request_test.cc2
-rw-r--r--system/gd/hci/security_interface.h2
-rw-r--r--system/gd/hci/uuid_unittest.cc2
-rw-r--r--system/gd/lpp/lpp_offload_interface.h2
-rw-r--r--system/gd/lpp/lpp_offload_interface_mock.h2
-rw-r--r--system/gd/lpp/lpp_offload_manager.cc2
-rw-r--r--system/gd/lpp/lpp_offload_manager.h2
-rw-r--r--system/gd/metrics/bluetooth_event.cc2
-rw-r--r--system/gd/metrics/bluetooth_event.h2
-rw-r--r--system/gd/metrics/chromeos/metrics.cc2
-rw-r--r--system/gd/metrics/chromeos/metrics_allowlist.cc2
-rw-r--r--system/gd/metrics/chromeos/metrics_allowlist.h2
-rw-r--r--system/gd/metrics/chromeos/metrics_event.cc2
-rw-r--r--system/gd/metrics/chromeos/metrics_event.h2
-rw-r--r--system/gd/metrics/counter_metrics.cc2
-rw-r--r--system/gd/metrics/counter_metrics.h2
-rw-r--r--system/gd/metrics/counter_metrics_unittest.cc2
-rw-r--r--system/gd/metrics/linux/metrics.cc2
-rw-r--r--system/gd/metrics/metrics.h2
-rw-r--r--system/gd/metrics/utils.cc2
-rw-r--r--system/gd/metrics/utils.h2
-rw-r--r--system/gd/module.cc33
-rw-r--r--system/gd/module.h8
-rw-r--r--system/gd/module_unittest.cc8
-rw-r--r--system/gd/os/alarm.h2
-rw-r--r--system/gd/os/alarm_benchmark.cc2
-rw-r--r--system/gd/os/android/metrics.cc19
-rw-r--r--system/gd/os/android/parameter_provider.cc2
-rw-r--r--system/gd/os/android/system_properties.cc2
-rw-r--r--system/gd/os/bt_keystore.h2
-rw-r--r--system/gd/os/chromeos/metrics.cc5
-rw-r--r--system/gd/os/chromeos/parameter_provider.cc2
-rw-r--r--system/gd/os/chromeos/system_properties.cc2
-rw-r--r--system/gd/os/fake_timer/fake_timerfd.cc2
-rw-r--r--system/gd/os/fake_timer/fake_timerfd.h2
-rw-r--r--system/gd/os/files.h2
-rw-r--r--system/gd/os/fuzz/dev_null_queue.h2
-rw-r--r--system/gd/os/fuzz/fuzz_inject_queue.h2
-rw-r--r--system/gd/os/handler.cc2
-rw-r--r--system/gd/os/handler.h2
-rw-r--r--system/gd/os/handler_unittest.cc2
-rw-r--r--system/gd/os/host/metrics.cc3
-rw-r--r--system/gd/os/host/parameter_provider.cc2
-rw-r--r--system/gd/os/host/system_properties.cc2
-rw-r--r--system/gd/os/linux/metrics.cc5
-rw-r--r--system/gd/os/linux/parameter_provider.cc2
-rw-r--r--system/gd/os/linux/system_properties.cc2
-rw-r--r--system/gd/os/linux_generic/alarm.cc8
-rw-r--r--system/gd/os/linux_generic/alarm_timerfd_unittest.cc2
-rw-r--r--system/gd/os/linux_generic/alarm_unittest.cc2
-rw-r--r--system/gd/os/linux_generic/files.cc2
-rw-r--r--system/gd/os/linux_generic/files_test.cc2
-rw-r--r--system/gd/os/linux_generic/linux.h2
-rw-r--r--system/gd/os/linux_generic/mgmt.cc2
-rw-r--r--system/gd/os/linux_generic/queue_unittest.cc2
-rw-r--r--system/gd/os/linux_generic/reactive_semaphore.cc2
-rw-r--r--system/gd/os/linux_generic/reactive_semaphore.h2
-rw-r--r--system/gd/os/linux_generic/reactor.cc2
-rw-r--r--system/gd/os/linux_generic/reactor_unittest.cc2
-rw-r--r--system/gd/os/linux_generic/repeating_alarm.cc2
-rw-r--r--system/gd/os/linux_generic/repeating_alarm_unittest.cc2
-rw-r--r--system/gd/os/linux_generic/thread.cc2
-rw-r--r--system/gd/os/linux_generic/thread_unittest.cc2
-rw-r--r--system/gd/os/metrics.h8
-rw-r--r--system/gd/os/mock_queue.h2
-rw-r--r--system/gd/os/parameter_provider.h2
-rw-r--r--system/gd/os/queue.h2
-rw-r--r--system/gd/os/queue_benchmark.cc2
-rw-r--r--system/gd/os/rand.h2
-rw-r--r--system/gd/os/reactor.h2
-rw-r--r--system/gd/os/repeating_alarm.h2
-rw-r--r--system/gd/os/system_properties.h2
-rw-r--r--system/gd/os/system_properties_common.cc2
-rw-r--r--system/gd/os/system_properties_common_test.cc2
-rw-r--r--system/gd/os/thread.h2
-rw-r--r--system/gd/os/thread_benchmark.cc2
-rw-r--r--system/gd/os/utils.h2
-rw-r--r--system/gd/packet/base_packet_builder.h2
-rw-r--r--system/gd/packet/base_struct.h2
-rw-r--r--system/gd/packet/bit_inserter.cc2
-rw-r--r--system/gd/packet/bit_inserter.h2
-rw-r--r--system/gd/packet/bit_inserter_unittest.cc2
-rw-r--r--system/gd/packet/byte_inserter.cc2
-rw-r--r--system/gd/packet/byte_inserter.h2
-rw-r--r--system/gd/packet/byte_observer.cc2
-rw-r--r--system/gd/packet/byte_observer.h2
-rw-r--r--system/gd/packet/checksum_type_checker.h2
-rw-r--r--system/gd/packet/custom_field_fixed_size_interface.h2
-rw-r--r--system/gd/packet/custom_type_checker.h2
-rw-r--r--system/gd/packet/endian_inserter.h2
-rw-r--r--system/gd/packet/fragmenting_inserter.cc2
-rw-r--r--system/gd/packet/fragmenting_inserter.h2
-rw-r--r--system/gd/packet/fragmenting_inserter_unittest.cc2
-rw-r--r--system/gd/packet/iterator.cc2
-rw-r--r--system/gd/packet/iterator.h2
-rw-r--r--system/gd/packet/packet_builder.h2
-rw-r--r--system/gd/packet/packet_builder_unittest.cc2
-rw-r--r--system/gd/packet/packet_struct.h2
-rw-r--r--system/gd/packet/packet_view.cc2
-rw-r--r--system/gd/packet/packet_view.h2
-rw-r--r--system/gd/packet/packet_view_unittest.cc2
-rw-r--r--system/gd/packet/parser/checksum_def.cc2
-rw-r--r--system/gd/packet/parser/checksum_def.h2
-rw-r--r--system/gd/packet/parser/custom_field_def.cc2
-rw-r--r--system/gd/packet/parser/custom_field_def.h2
-rw-r--r--system/gd/packet/parser/declarations.h2
-rw-r--r--system/gd/packet/parser/enum_def.cc2
-rw-r--r--system/gd/packet/parser/enum_def.h2
-rw-r--r--system/gd/packet/parser/enum_gen.cc2
-rw-r--r--system/gd/packet/parser/enum_gen.h2
-rw-r--r--system/gd/packet/parser/field_list.h2
-rw-r--r--system/gd/packet/parser/fields/all_fields.h2
-rw-r--r--system/gd/packet/parser/fields/array_field.cc2
-rw-r--r--system/gd/packet/parser/fields/array_field.h2
-rw-r--r--system/gd/packet/parser/fields/body_field.cc2
-rw-r--r--system/gd/packet/parser/fields/body_field.h2
-rw-r--r--system/gd/packet/parser/fields/checksum_field.cc2
-rw-r--r--system/gd/packet/parser/fields/checksum_field.h2
-rw-r--r--system/gd/packet/parser/fields/checksum_start_field.cc2
-rw-r--r--system/gd/packet/parser/fields/checksum_start_field.h2
-rw-r--r--system/gd/packet/parser/fields/count_field.cc2
-rw-r--r--system/gd/packet/parser/fields/count_field.h2
-rw-r--r--system/gd/packet/parser/fields/custom_field.cc2
-rw-r--r--system/gd/packet/parser/fields/custom_field.h2
-rw-r--r--system/gd/packet/parser/fields/custom_field_fixed_size.cc2
-rw-r--r--system/gd/packet/parser/fields/custom_field_fixed_size.h2
-rw-r--r--system/gd/packet/parser/fields/enum_field.cc2
-rw-r--r--system/gd/packet/parser/fields/enum_field.h2
-rw-r--r--system/gd/packet/parser/fields/fixed_enum_field.cc2
-rw-r--r--system/gd/packet/parser/fields/fixed_enum_field.h2
-rw-r--r--system/gd/packet/parser/fields/fixed_field.cc2
-rw-r--r--system/gd/packet/parser/fields/fixed_field.h2
-rw-r--r--system/gd/packet/parser/fields/fixed_scalar_field.cc2
-rw-r--r--system/gd/packet/parser/fields/fixed_scalar_field.h2
-rw-r--r--system/gd/packet/parser/fields/group_field.cc2
-rw-r--r--system/gd/packet/parser/fields/group_field.h2
-rw-r--r--system/gd/packet/parser/fields/packet_field.cc2
-rw-r--r--system/gd/packet/parser/fields/packet_field.h2
-rw-r--r--system/gd/packet/parser/fields/padding_field.cc2
-rw-r--r--system/gd/packet/parser/fields/padding_field.h2
-rw-r--r--system/gd/packet/parser/fields/payload_field.cc2
-rw-r--r--system/gd/packet/parser/fields/payload_field.h2
-rw-r--r--system/gd/packet/parser/fields/reserved_field.cc2
-rw-r--r--system/gd/packet/parser/fields/reserved_field.h2
-rw-r--r--system/gd/packet/parser/fields/scalar_field.cc2
-rw-r--r--system/gd/packet/parser/fields/scalar_field.h2
-rw-r--r--system/gd/packet/parser/fields/size_field.cc2
-rw-r--r--system/gd/packet/parser/fields/size_field.h2
-rw-r--r--system/gd/packet/parser/fields/struct_field.cc2
-rw-r--r--system/gd/packet/parser/fields/struct_field.h2
-rw-r--r--system/gd/packet/parser/fields/variable_length_struct_field.cc2
-rw-r--r--system/gd/packet/parser/fields/variable_length_struct_field.h2
-rw-r--r--system/gd/packet/parser/fields/vector_field.cc2
-rw-r--r--system/gd/packet/parser/fields/vector_field.h2
-rw-r--r--system/gd/packet/parser/gen_cpp.cc2
-rw-r--r--system/gd/packet/parser/logging.h2
-rw-r--r--system/gd/packet/parser/main.cc2
-rw-r--r--system/gd/packet/parser/packet_def.cc2
-rw-r--r--system/gd/packet/parser/packet_def.h2
-rw-r--r--system/gd/packet/parser/packet_dependency.cc2
-rw-r--r--system/gd/packet/parser/packet_dependency.h2
-rw-r--r--system/gd/packet/parser/parent_def.cc2
-rw-r--r--system/gd/packet/parser/parent_def.h2
-rw-r--r--system/gd/packet/parser/parse_location.h2
-rw-r--r--system/gd/packet/parser/size.h2
-rw-r--r--system/gd/packet/parser/struct_def.cc2
-rw-r--r--system/gd/packet/parser/struct_def.h2
-rw-r--r--system/gd/packet/parser/struct_parser_generator.cc2
-rw-r--r--system/gd/packet/parser/struct_parser_generator.h2
-rw-r--r--system/gd/packet/parser/test/generated_packet_test.cc2
-rw-r--r--system/gd/packet/parser/test/simple_sum.h2
-rw-r--r--system/gd/packet/parser/test/six_bytes.cc2
-rw-r--r--system/gd/packet/parser/test/six_bytes.h2
-rw-r--r--system/gd/packet/parser/test/variable.cc2
-rw-r--r--system/gd/packet/parser/test/variable.h2
-rw-r--r--system/gd/packet/parser/type_def.h2
-rw-r--r--system/gd/packet/parser/util.h2
-rw-r--r--system/gd/packet/raw_builder.cc2
-rw-r--r--system/gd/packet/raw_builder.h2
-rw-r--r--system/gd/packet/raw_builder_unittest.cc2
-rw-r--r--system/gd/packet/view.cc2
-rw-r--r--system/gd/packet/view.h2
-rw-r--r--system/gd/proto/bluetooth/metrics/bluetooth.proto276
-rw-r--r--system/gd/rust/linux/service/src/interface_manager.rs48
-rw-r--r--system/gd/rust/linux/service/src/main.rs136
-rw-r--r--system/gd/rust/linux/stack/src/bluetooth.rs27
-rw-r--r--system/gd/rust/linux/stack/src/lib.rs8
-rw-r--r--system/gd/rust/topshim/controller/controller_shim.cc2
-rw-r--r--system/gd/storage/classic_device.cc2
-rw-r--r--system/gd/storage/classic_device.h2
-rw-r--r--system/gd/storage/classic_device_test.cc2
-rw-r--r--system/gd/storage/config_cache.cc2
-rw-r--r--system/gd/storage/config_cache.h2
-rw-r--r--system/gd/storage/config_cache_helper.cc2
-rw-r--r--system/gd/storage/config_cache_helper.h2
-rw-r--r--system/gd/storage/config_cache_helper_test.cc2
-rw-r--r--system/gd/storage/config_cache_test.cc2
-rw-r--r--system/gd/storage/device.cc2
-rw-r--r--system/gd/storage/device.h2
-rw-r--r--system/gd/storage/device_test.cc2
-rw-r--r--system/gd/storage/le_device.cc2
-rw-r--r--system/gd/storage/le_device.h2
-rw-r--r--system/gd/storage/le_device_test.cc2
-rw-r--r--system/gd/storage/legacy_config_file.cc2
-rw-r--r--system/gd/storage/legacy_config_file.h2
-rw-r--r--system/gd/storage/legacy_config_file_test.cc2
-rw-r--r--system/gd/storage/mutation.cc2
-rw-r--r--system/gd/storage/mutation.h2
-rw-r--r--system/gd/storage/mutation_entry.cc2
-rw-r--r--system/gd/storage/mutation_entry.h2
-rw-r--r--system/gd/storage/mutation_test.cc2
-rw-r--r--system/gd/storage/serializable.h2
-rw-r--r--system/gd/storage/storage_module.cc2
-rw-r--r--system/gd/storage/storage_module.h2
-rw-r--r--system/gd/storage/storage_module_test.cc2
-rw-r--r--system/gd/sysprops/sysprops_module.cc2
-rw-r--r--system/gd/sysprops/sysprops_module.h2
-rw-r--r--system/gd/sysprops/sysprops_module_test.cc2
-rw-r--r--system/include/hardware/bluetooth_headset_interface.h3
-rw-r--r--system/include/hardware/bt_sock.h19
-rw-r--r--system/linux_include/log/log.h24
-rw-r--r--system/main/shim/metrics_api.cc10
-rw-r--r--system/main/shim/metrics_api.h8
-rw-r--r--system/main/shim/stack.cc17
-rw-r--r--system/main/test/main_shim_test.cc13
-rw-r--r--system/osi/BUILD.gn1
-rw-r--r--system/pdl/hci/hci_packets.pdl4
-rw-r--r--system/stack/Android.bp35
-rw-r--r--system/stack/BUILD.gn3
-rw-r--r--system/stack/btm/btm_ble_sec.cc41
-rw-r--r--system/stack/btm/btm_sco.cc5
-rw-r--r--system/stack/btm/btm_sec.cc28
-rw-r--r--system/stack/btm/security_event_parser.cc16
-rw-r--r--system/stack/btu/btu_hcif.cc121
-rw-r--r--system/stack/fuzzers/l2cap_fuzzer.cc20
-rw-r--r--system/stack/gatt/gatt_api.cc9
-rw-r--r--system/stack/hid/hidd_api.cc48
-rw-r--r--system/stack/hid/hidd_conn.cc33
-rw-r--r--system/stack/hid/hidh_api.cc30
-rw-r--r--system/stack/hid/hidh_conn.cc22
-rw-r--r--system/stack/include/stack_metrics_logging.h69
-rw-r--r--system/stack/l2cap/l2c_ble.cc9
-rw-r--r--system/stack/metrics/stack_metrics_logging.cc101
-rw-r--r--system/stack/mmc/metrics/mmc_rtt_logger.cc5
-rw-r--r--system/stack/rfcomm/port_api.cc4
-rw-r--r--system/stack/rfcomm/port_rfc.cc41
-rw-r--r--system/stack/rfcomm/rfc_l2cap_if.cc54
-rw-r--r--system/stack/sdp/sdp_utils.cc38
-rw-r--r--system/stack/smp/smp_l2c.cc7
-rw-r--r--system/stack/smp/smp_utils.cc10
-rw-r--r--system/stack/test/btm/stack_btm_power_mode_test.cc9
-rw-r--r--system/stack/test/btm/stack_btm_sec_test.cc5
-rw-r--r--system/stack/test/btm/stack_btm_test.cc39
-rw-r--r--system/stack/test/btm_iso_test.cc21
-rw-r--r--system/stack/test/connection_manager_test.cc59
-rw-r--r--system/stack/test/eatt/eatt_test.cc9
-rw-r--r--system/stack/test/stack_acl_test.cc6
-rw-r--r--system/stack/test/stack_l2cap_test.cc14
-rw-r--r--system/test/Android.bp7
-rw-r--r--system/test/README.md81
-rw-r--r--system/test/mock/mock_main_shim_entry.cc12
-rw-r--r--system/test/mock/mock_main_shim_entry.h9
-rw-r--r--system/test/mock/mock_main_shim_metrics_api.cc7
-rw-r--r--system/test/mock/mock_main_shim_metrics_api.h14
-rw-r--r--system/test/mock/mock_stack_metrics_logging.cc151
-rw-r--r--system/test/mock/mock_stack_metrics_logging.h254
1051 files changed, 14473 insertions, 14514 deletions
diff --git a/android/app/Android.bp b/android/app/Android.bp
index 6bdbe3282b..7606a10b73 100644
--- a/android/app/Android.bp
+++ b/android/app/Android.bp
@@ -246,7 +246,6 @@ android_library {
"ExtraText",
"ExtraTranslation",
"GestureBackNavigation",
- "GetterSetterNullability",
"GuardedLogInvocation",
"HandlerLeak",
"InflateParams",
@@ -319,7 +318,6 @@ android_app {
"ExtraText",
"ExtraTranslation",
"GestureBackNavigation",
- "GetterSetterNullability",
"GuardedLogInvocation",
"HandlerLeak",
"InflateParams",
diff --git a/android/app/aidl/android/bluetooth/BluetoothAudioConfig.aidl b/android/app/aidl/android/bluetooth/BluetoothAudioConfig.aidl
index 2ef113d9fa..63be5cff87 100644
--- a/android/app/aidl/android/bluetooth/BluetoothAudioConfig.aidl
+++ b/android/app/aidl/android/bluetooth/BluetoothAudioConfig.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2009 The Android Open Source Project
+ * Copyright (C) 2009 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.
diff --git a/android/app/aidl/android/bluetooth/BluetoothAvrcpPlayerSettings.aidl b/android/app/aidl/android/bluetooth/BluetoothAvrcpPlayerSettings.aidl
index 41b8af6d78..590fd63eda 100644
--- a/android/app/aidl/android/bluetooth/BluetoothAvrcpPlayerSettings.aidl
+++ b/android/app/aidl/android/bluetooth/BluetoothAvrcpPlayerSettings.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 The Android Open Source Project
+ * Copyright (C) 2015 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.
diff --git a/android/app/aidl/android/bluetooth/BluetoothClass.aidl b/android/app/aidl/android/bluetooth/BluetoothClass.aidl
index 8699b1eee3..124ee53760 100644
--- a/android/app/aidl/android/bluetooth/BluetoothClass.aidl
+++ b/android/app/aidl/android/bluetooth/BluetoothClass.aidl
@@ -5,7 +5,7 @@
* 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
+ * 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,
diff --git a/android/app/aidl/android/bluetooth/BluetoothCodecConfig.aidl b/android/app/aidl/android/bluetooth/BluetoothCodecConfig.aidl
index 58906374ba..553e66e1da 100644
--- a/android/app/aidl/android/bluetooth/BluetoothCodecConfig.aidl
+++ b/android/app/aidl/android/bluetooth/BluetoothCodecConfig.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2016 The Android Open Source Project
+ * Copyright (C) 2016 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.
diff --git a/android/app/aidl/android/bluetooth/BluetoothCodecStatus.aidl b/android/app/aidl/android/bluetooth/BluetoothCodecStatus.aidl
index f674db77bd..f9c3a3de2f 100644
--- a/android/app/aidl/android/bluetooth/BluetoothCodecStatus.aidl
+++ b/android/app/aidl/android/bluetooth/BluetoothCodecStatus.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2017 The Android Open Source Project
+ * Copyright (C) 2017 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.
diff --git a/android/app/aidl/android/bluetooth/BluetoothCodecType.aidl b/android/app/aidl/android/bluetooth/BluetoothCodecType.aidl
index 2365b126ca..dfd81057ee 100644
--- a/android/app/aidl/android/bluetooth/BluetoothCodecType.aidl
+++ b/android/app/aidl/android/bluetooth/BluetoothCodecType.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 The Android Open Source Project
+ * Copyright (C) 2024 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.
diff --git a/android/app/aidl/android/bluetooth/BluetoothGattCharacteristic.aidl b/android/app/aidl/android/bluetooth/BluetoothGattCharacteristic.aidl
index 463b7a70b7..bbb8623e21 100644
--- a/android/app/aidl/android/bluetooth/BluetoothGattCharacteristic.aidl
+++ b/android/app/aidl/android/bluetooth/BluetoothGattCharacteristic.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2016 The Android Open Source Project
+ * Copyright (C) 2016 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.
diff --git a/android/app/aidl/android/bluetooth/BluetoothGattDescriptor.aidl b/android/app/aidl/android/bluetooth/BluetoothGattDescriptor.aidl
index 6d4cdeb848..4393273316 100644
--- a/android/app/aidl/android/bluetooth/BluetoothGattDescriptor.aidl
+++ b/android/app/aidl/android/bluetooth/BluetoothGattDescriptor.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2016 The Android Open Source Project
+ * Copyright (C) 2016 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.
diff --git a/android/app/aidl/android/bluetooth/BluetoothGattIncludedService.aidl b/android/app/aidl/android/bluetooth/BluetoothGattIncludedService.aidl
index d911973467..1ef427edc3 100644
--- a/android/app/aidl/android/bluetooth/BluetoothGattIncludedService.aidl
+++ b/android/app/aidl/android/bluetooth/BluetoothGattIncludedService.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2016 The Android Open Source Project
+ * Copyright (C) 2016 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.
diff --git a/android/app/aidl/android/bluetooth/BluetoothGattService.aidl b/android/app/aidl/android/bluetooth/BluetoothGattService.aidl
index 8e72ba91a4..84314d2072 100644
--- a/android/app/aidl/android/bluetooth/BluetoothGattService.aidl
+++ b/android/app/aidl/android/bluetooth/BluetoothGattService.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2016 The Android Open Source Project
+ * Copyright (C) 2016 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.
diff --git a/android/app/aidl/android/bluetooth/BluetoothHeadsetClientCall.aidl b/android/app/aidl/android/bluetooth/BluetoothHeadsetClientCall.aidl
index 5403d5149c..35f792387e 100644
--- a/android/app/aidl/android/bluetooth/BluetoothHeadsetClientCall.aidl
+++ b/android/app/aidl/android/bluetooth/BluetoothHeadsetClientCall.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2014 The Android Open Source Project
+ * Copyright (C) 2014 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.
diff --git a/android/app/aidl/android/bluetooth/BluetoothHearingAid.aidl b/android/app/aidl/android/bluetooth/BluetoothHearingAid.aidl
index 48c4772c03..bcb2466bda 100644
--- a/android/app/aidl/android/bluetooth/BluetoothHearingAid.aidl
+++ b/android/app/aidl/android/bluetooth/BluetoothHearingAid.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 The Android Open Source Project
+ * Copyright (C) 2024 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.
diff --git a/android/app/aidl/android/bluetooth/BluetoothHidDeviceAppQosSettings.aidl b/android/app/aidl/android/bluetooth/BluetoothHidDeviceAppQosSettings.aidl
index 14f91140af..74f51a8037 100644
--- a/android/app/aidl/android/bluetooth/BluetoothHidDeviceAppQosSettings.aidl
+++ b/android/app/aidl/android/bluetooth/BluetoothHidDeviceAppQosSettings.aidl
@@ -5,7 +5,7 @@
** 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
+** 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,
diff --git a/android/app/aidl/android/bluetooth/BluetoothHidDeviceAppSdpSettings.aidl b/android/app/aidl/android/bluetooth/BluetoothHidDeviceAppSdpSettings.aidl
index 87dd10ee15..a55a794c6e 100644
--- a/android/app/aidl/android/bluetooth/BluetoothHidDeviceAppSdpSettings.aidl
+++ b/android/app/aidl/android/bluetooth/BluetoothHidDeviceAppSdpSettings.aidl
@@ -5,7 +5,7 @@
** 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
+** 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,
diff --git a/android/app/aidl/android/bluetooth/BluetoothLeAudioCodecConfig.aidl b/android/app/aidl/android/bluetooth/BluetoothLeAudioCodecConfig.aidl
index e32217eff7..3eb42f18e9 100644
--- a/android/app/aidl/android/bluetooth/BluetoothLeAudioCodecConfig.aidl
+++ b/android/app/aidl/android/bluetooth/BluetoothLeAudioCodecConfig.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/aidl/android/bluetooth/BluetoothLeAudioCodecStatus.aidl b/android/app/aidl/android/bluetooth/BluetoothLeAudioCodecStatus.aidl
index 7c50d6ebe9..52cdf692bc 100644
--- a/android/app/aidl/android/bluetooth/BluetoothLeAudioCodecStatus.aidl
+++ b/android/app/aidl/android/bluetooth/BluetoothLeAudioCodecStatus.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/aidl/android/bluetooth/BluetoothLeAudioContentMetadata.aidl b/android/app/aidl/android/bluetooth/BluetoothLeAudioContentMetadata.aidl
index 8962810c62..eb4712a9bb 100644
--- a/android/app/aidl/android/bluetooth/BluetoothLeAudioContentMetadata.aidl
+++ b/android/app/aidl/android/bluetooth/BluetoothLeAudioContentMetadata.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/aidl/android/bluetooth/BluetoothLeBroadcastMetadata.aidl b/android/app/aidl/android/bluetooth/BluetoothLeBroadcastMetadata.aidl
index eb00836ec0..5ce8f6ba30 100644
--- a/android/app/aidl/android/bluetooth/BluetoothLeBroadcastMetadata.aidl
+++ b/android/app/aidl/android/bluetooth/BluetoothLeBroadcastMetadata.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/aidl/android/bluetooth/BluetoothLeBroadcastReceiveState.aidl b/android/app/aidl/android/bluetooth/BluetoothLeBroadcastReceiveState.aidl
index e3f13b0fbc..1ae4036cdf 100644
--- a/android/app/aidl/android/bluetooth/BluetoothLeBroadcastReceiveState.aidl
+++ b/android/app/aidl/android/bluetooth/BluetoothLeBroadcastReceiveState.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/aidl/android/bluetooth/BluetoothLeBroadcastSettings.aidl b/android/app/aidl/android/bluetooth/BluetoothLeBroadcastSettings.aidl
index 69ec550745..b36d69c374 100644
--- a/android/app/aidl/android/bluetooth/BluetoothLeBroadcastSettings.aidl
+++ b/android/app/aidl/android/bluetooth/BluetoothLeBroadcastSettings.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 The Android Open Source Project
+ * Copyright (C) 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.
diff --git a/android/app/aidl/android/bluetooth/BluetoothSinkAudioPolicy.aidl b/android/app/aidl/android/bluetooth/BluetoothSinkAudioPolicy.aidl
index 740249c84f..edb81dd6a2 100644
--- a/android/app/aidl/android/bluetooth/BluetoothSinkAudioPolicy.aidl
+++ b/android/app/aidl/android/bluetooth/BluetoothSinkAudioPolicy.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/aidl/android/bluetooth/IAudioInputCallback.aidl b/android/app/aidl/android/bluetooth/IAudioInputCallback.aidl
index 133dfbebbb..9b358940bd 100644
--- a/android/app/aidl/android/bluetooth/IAudioInputCallback.aidl
+++ b/android/app/aidl/android/bluetooth/IAudioInputCallback.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 The Android Open Source Project
+ * Copyright (C) 2024 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.
diff --git a/android/app/aidl/android/bluetooth/IBluetooth.aidl b/android/app/aidl/android/bluetooth/IBluetooth.aidl
index b9cf6bca14..d8a5421d6f 100644
--- a/android/app/aidl/android/bluetooth/IBluetooth.aidl
+++ b/android/app/aidl/android/bluetooth/IBluetooth.aidl
@@ -5,7 +5,7 @@
* 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
+ * 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,
@@ -100,7 +100,9 @@ interface IBluetooth
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
List<BluetoothDevice> getBondedDevices(in AttributionSource attributionSource);
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean createBond(in BluetoothDevice device, in int transport, in OobData p192Data, in OobData p256Data, in AttributionSource attributionSource);
+ boolean createBond(in BluetoothDevice device, in int transport, in AttributionSource attributionSource);
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
+ boolean createBondOutOfBand(in BluetoothDevice device, in int transport, in OobData p192Data, in OobData p256Data, in AttributionSource attributionSource);
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
boolean cancelBondProcess(in BluetoothDevice device, in AttributionSource attributionSource);
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
diff --git a/android/app/aidl/android/bluetooth/IBluetoothA2dp.aidl b/android/app/aidl/android/bluetooth/IBluetoothA2dp.aidl
index fa5d1362ac..3eeaf4de82 100644
--- a/android/app/aidl/android/bluetooth/IBluetoothA2dp.aidl
+++ b/android/app/aidl/android/bluetooth/IBluetoothA2dp.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2008 The Android Open Source Project
+ * Copyright (C) 2008 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.
diff --git a/android/app/aidl/android/bluetooth/IBluetoothA2dpSink.aidl b/android/app/aidl/android/bluetooth/IBluetoothA2dpSink.aidl
index 53c12167bb..0e09962668 100644
--- a/android/app/aidl/android/bluetooth/IBluetoothA2dpSink.aidl
+++ b/android/app/aidl/android/bluetooth/IBluetoothA2dpSink.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2014 The Android Open Source Project
+ * Copyright (C) 2014 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.
diff --git a/android/app/aidl/android/bluetooth/IBluetoothAvrcpController.aidl b/android/app/aidl/android/bluetooth/IBluetoothAvrcpController.aidl
index 4eae036576..f9226ccca6 100644
--- a/android/app/aidl/android/bluetooth/IBluetoothAvrcpController.aidl
+++ b/android/app/aidl/android/bluetooth/IBluetoothAvrcpController.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2014 The Android Open Source Project
+ * Copyright (C) 2014 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.
diff --git a/android/app/aidl/android/bluetooth/IBluetoothCallback.aidl b/android/app/aidl/android/bluetooth/IBluetoothCallback.aidl
index 9b2888eadb..6101044e29 100644
--- a/android/app/aidl/android/bluetooth/IBluetoothCallback.aidl
+++ b/android/app/aidl/android/bluetooth/IBluetoothCallback.aidl
@@ -5,7 +5,7 @@
* 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
+ * 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,
diff --git a/android/app/aidl/android/bluetooth/IBluetoothConnectionCallback.aidl b/android/app/aidl/android/bluetooth/IBluetoothConnectionCallback.aidl
index 56de49c519..acbccedbb8 100644
--- a/android/app/aidl/android/bluetooth/IBluetoothConnectionCallback.aidl
+++ b/android/app/aidl/android/bluetooth/IBluetoothConnectionCallback.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/android/app/aidl/android/bluetooth/IBluetoothGatt.aidl b/android/app/aidl/android/bluetooth/IBluetoothGatt.aidl
index 40976dbf00..225da3e126 100644
--- a/android/app/aidl/android/bluetooth/IBluetoothGatt.aidl
+++ b/android/app/aidl/android/bluetooth/IBluetoothGatt.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2013 The Android Open Source Project
+ * Copyright (C) 2013 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.
diff --git a/android/app/aidl/android/bluetooth/IBluetoothGattCallback.aidl b/android/app/aidl/android/bluetooth/IBluetoothGattCallback.aidl
index 78fc874b1c..81ec765973 100644
--- a/android/app/aidl/android/bluetooth/IBluetoothGattCallback.aidl
+++ b/android/app/aidl/android/bluetooth/IBluetoothGattCallback.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2013 The Android Open Source Project
+ * Copyright (C) 2013 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.
diff --git a/android/app/aidl/android/bluetooth/IBluetoothGattServerCallback.aidl b/android/app/aidl/android/bluetooth/IBluetoothGattServerCallback.aidl
index f79546dd34..cc0ff314de 100644
--- a/android/app/aidl/android/bluetooth/IBluetoothGattServerCallback.aidl
+++ b/android/app/aidl/android/bluetooth/IBluetoothGattServerCallback.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2017 The Android Open Source Project
+ * Copyright (C) 2017 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.
diff --git a/android/app/aidl/android/bluetooth/IBluetoothHapClientCallback.aidl b/android/app/aidl/android/bluetooth/IBluetoothHapClientCallback.aidl
index 2480b305e9..96d1c88eb0 100644
--- a/android/app/aidl/android/bluetooth/IBluetoothHapClientCallback.aidl
+++ b/android/app/aidl/android/bluetooth/IBluetoothHapClientCallback.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/aidl/android/bluetooth/IBluetoothHciVendorSpecificCallback.aidl b/android/app/aidl/android/bluetooth/IBluetoothHciVendorSpecificCallback.aidl
index 2aac21b158..ee122fd6b3 100644
--- a/android/app/aidl/android/bluetooth/IBluetoothHciVendorSpecificCallback.aidl
+++ b/android/app/aidl/android/bluetooth/IBluetoothHciVendorSpecificCallback.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 The Android Open Source Project
+ * Copyright (C) 2024 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.
diff --git a/android/app/aidl/android/bluetooth/IBluetoothHeadset.aidl b/android/app/aidl/android/bluetooth/IBluetoothHeadset.aidl
index 3b3292cd16..6653bd2320 100644
--- a/android/app/aidl/android/bluetooth/IBluetoothHeadset.aidl
+++ b/android/app/aidl/android/bluetooth/IBluetoothHeadset.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2008 The Android Open Source Project
+ * Copyright (C) 2008 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.
diff --git a/android/app/aidl/android/bluetooth/IBluetoothHeadsetClient.aidl b/android/app/aidl/android/bluetooth/IBluetoothHeadsetClient.aidl
index 59c5f98bfb..2693a0df0a 100644
--- a/android/app/aidl/android/bluetooth/IBluetoothHeadsetClient.aidl
+++ b/android/app/aidl/android/bluetooth/IBluetoothHeadsetClient.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2014 The Android Open Source Project
+ * Copyright (C) 2014 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.
diff --git a/android/app/aidl/android/bluetooth/IBluetoothHearingAid.aidl b/android/app/aidl/android/bluetooth/IBluetoothHearingAid.aidl
index 29e5a1f792..e21da24ef0 100644
--- a/android/app/aidl/android/bluetooth/IBluetoothHearingAid.aidl
+++ b/android/app/aidl/android/bluetooth/IBluetoothHearingAid.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 The Android Open Source Project
+ * Copyright (C) 2018 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.
diff --git a/android/app/aidl/android/bluetooth/IBluetoothHidDevice.aidl b/android/app/aidl/android/bluetooth/IBluetoothHidDevice.aidl
index c53d1e63fb..dd82eb5ba1 100644
--- a/android/app/aidl/android/bluetooth/IBluetoothHidDevice.aidl
+++ b/android/app/aidl/android/bluetooth/IBluetoothHidDevice.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2016 The Android Open Source Project
+ * Copyright (C) 2016 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.
diff --git a/android/app/aidl/android/bluetooth/IBluetoothHidHost.aidl b/android/app/aidl/android/bluetooth/IBluetoothHidHost.aidl
index 69ffdc227a..7d44385b1e 100644
--- a/android/app/aidl/android/bluetooth/IBluetoothHidHost.aidl
+++ b/android/app/aidl/android/bluetooth/IBluetoothHidHost.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2012 The Android Open Source Project
+ * Copyright (C) 2012 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.
diff --git a/android/app/aidl/android/bluetooth/IBluetoothLeAudioCallback.aidl b/android/app/aidl/android/bluetooth/IBluetoothLeAudioCallback.aidl
index f333405f5e..c1c0480bba 100644
--- a/android/app/aidl/android/bluetooth/IBluetoothLeAudioCallback.aidl
+++ b/android/app/aidl/android/bluetooth/IBluetoothLeAudioCallback.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/aidl/android/bluetooth/IBluetoothLeBroadcastAssistant.aidl b/android/app/aidl/android/bluetooth/IBluetoothLeBroadcastAssistant.aidl
index 54b947c061..9c00f3b8c2 100644
--- a/android/app/aidl/android/bluetooth/IBluetoothLeBroadcastAssistant.aidl
+++ b/android/app/aidl/android/bluetooth/IBluetoothLeBroadcastAssistant.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/aidl/android/bluetooth/IBluetoothLeBroadcastAssistantCallback.aidl b/android/app/aidl/android/bluetooth/IBluetoothLeBroadcastAssistantCallback.aidl
index 9a09254c50..eff415a5b5 100644
--- a/android/app/aidl/android/bluetooth/IBluetoothLeBroadcastAssistantCallback.aidl
+++ b/android/app/aidl/android/bluetooth/IBluetoothLeBroadcastAssistantCallback.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/aidl/android/bluetooth/IBluetoothLeBroadcastCallback.aidl b/android/app/aidl/android/bluetooth/IBluetoothLeBroadcastCallback.aidl
index aa9f3925cc..78289a01bc 100644
--- a/android/app/aidl/android/bluetooth/IBluetoothLeBroadcastCallback.aidl
+++ b/android/app/aidl/android/bluetooth/IBluetoothLeBroadcastCallback.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/aidl/android/bluetooth/IBluetoothMap.aidl b/android/app/aidl/android/bluetooth/IBluetoothMap.aidl
index 2862005ae2..798f34d08a 100644
--- a/android/app/aidl/android/bluetooth/IBluetoothMap.aidl
+++ b/android/app/aidl/android/bluetooth/IBluetoothMap.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2008 The Android Open Source Project
+ * Copyright (C) 2008 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.
diff --git a/android/app/aidl/android/bluetooth/IBluetoothMapClient.aidl b/android/app/aidl/android/bluetooth/IBluetoothMapClient.aidl
index a06a7fc0dc..6dba53c4c1 100644
--- a/android/app/aidl/android/bluetooth/IBluetoothMapClient.aidl
+++ b/android/app/aidl/android/bluetooth/IBluetoothMapClient.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2016 The Android Open Source Project
+ * Copyright (C) 2016 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.
diff --git a/android/app/aidl/android/bluetooth/IBluetoothMetadataListener.aidl b/android/app/aidl/android/bluetooth/IBluetoothMetadataListener.aidl
index e08919fedb..57f6fcb886 100644
--- a/android/app/aidl/android/bluetooth/IBluetoothMetadataListener.aidl
+++ b/android/app/aidl/android/bluetooth/IBluetoothMetadataListener.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/android/app/aidl/android/bluetooth/IBluetoothOobDataCallback.aidl b/android/app/aidl/android/bluetooth/IBluetoothOobDataCallback.aidl
index 00975b6bbe..a2a635fa45 100644
--- a/android/app/aidl/android/bluetooth/IBluetoothOobDataCallback.aidl
+++ b/android/app/aidl/android/bluetooth/IBluetoothOobDataCallback.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2021 The Android Open Source Project
+ * Copyright (C) 2021 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.
diff --git a/android/app/aidl/android/bluetooth/IBluetoothPan.aidl b/android/app/aidl/android/bluetooth/IBluetoothPan.aidl
index 2d9172fc97..b636e57c1e 100644
--- a/android/app/aidl/android/bluetooth/IBluetoothPan.aidl
+++ b/android/app/aidl/android/bluetooth/IBluetoothPan.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2012 The Android Open Source Project
+ * Copyright (C) 2012 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.
diff --git a/android/app/aidl/android/bluetooth/IBluetoothPanCallback.aidl b/android/app/aidl/android/bluetooth/IBluetoothPanCallback.aidl
index 898794a227..24886ae529 100644
--- a/android/app/aidl/android/bluetooth/IBluetoothPanCallback.aidl
+++ b/android/app/aidl/android/bluetooth/IBluetoothPanCallback.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2012 The Android Open Source Project
+ * Copyright (C) 2012 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.
diff --git a/android/app/aidl/android/bluetooth/IBluetoothPbap.aidl b/android/app/aidl/android/bluetooth/IBluetoothPbap.aidl
index 5d4f33431a..0e538b33a9 100644
--- a/android/app/aidl/android/bluetooth/IBluetoothPbap.aidl
+++ b/android/app/aidl/android/bluetooth/IBluetoothPbap.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2008 The Android Open Source Project
+ * Copyright (C) 2008 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.
diff --git a/android/app/aidl/android/bluetooth/IBluetoothPbapClient.aidl b/android/app/aidl/android/bluetooth/IBluetoothPbapClient.aidl
index 7cc66d08ac..cfc5cb78e0 100644
--- a/android/app/aidl/android/bluetooth/IBluetoothPbapClient.aidl
+++ b/android/app/aidl/android/bluetooth/IBluetoothPbapClient.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2016 The Android Open Source Project
+ * Copyright (C) 2016 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.
diff --git a/android/app/aidl/android/bluetooth/IBluetoothPreferredAudioProfilesCallback.aidl b/android/app/aidl/android/bluetooth/IBluetoothPreferredAudioProfilesCallback.aidl
index f7ab3ff975..534f54c28c 100644
--- a/android/app/aidl/android/bluetooth/IBluetoothPreferredAudioProfilesCallback.aidl
+++ b/android/app/aidl/android/bluetooth/IBluetoothPreferredAudioProfilesCallback.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 The Android Open Source Project
+ * Copyright (C) 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.
diff --git a/android/app/aidl/android/bluetooth/IBluetoothProfileServiceConnection.aidl b/android/app/aidl/android/bluetooth/IBluetoothProfileServiceConnection.aidl
index 5a048cf7e2..0a10d60c4e 100644
--- a/android/app/aidl/android/bluetooth/IBluetoothProfileServiceConnection.aidl
+++ b/android/app/aidl/android/bluetooth/IBluetoothProfileServiceConnection.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2014 The Android Open Source Project
+ * Copyright (C) 2014 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.
diff --git a/android/app/aidl/android/bluetooth/IBluetoothQualityReportReadyCallback.aidl b/android/app/aidl/android/bluetooth/IBluetoothQualityReportReadyCallback.aidl
index 7a92a20811..43d3473262 100644
--- a/android/app/aidl/android/bluetooth/IBluetoothQualityReportReadyCallback.aidl
+++ b/android/app/aidl/android/bluetooth/IBluetoothQualityReportReadyCallback.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 The Android Open Source Project
+ * Copyright (C) 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.
diff --git a/android/app/aidl/android/bluetooth/IBluetoothSap.aidl b/android/app/aidl/android/bluetooth/IBluetoothSap.aidl
index 94641bf4d5..019d66df0c 100644
--- a/android/app/aidl/android/bluetooth/IBluetoothSap.aidl
+++ b/android/app/aidl/android/bluetooth/IBluetoothSap.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2013 The Android Open Source Project
+ * Copyright (C) 2013 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.
diff --git a/android/app/aidl/android/bluetooth/IBluetoothSocketManager.aidl b/android/app/aidl/android/bluetooth/IBluetoothSocketManager.aidl
index ce2397ff33..bd54982d13 100644
--- a/android/app/aidl/android/bluetooth/IBluetoothSocketManager.aidl
+++ b/android/app/aidl/android/bluetooth/IBluetoothSocketManager.aidl
@@ -5,7 +5,7 @@
* 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
+ * 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,
diff --git a/android/app/aidl/android/bluetooth/IBluetoothVolumeControlCallback.aidl b/android/app/aidl/android/bluetooth/IBluetoothVolumeControlCallback.aidl
index e067989739..e5239b4b8b 100644
--- a/android/app/aidl/android/bluetooth/IBluetoothVolumeControlCallback.aidl
+++ b/android/app/aidl/android/bluetooth/IBluetoothVolumeControlCallback.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/aidl/android/bluetooth/IDistanceMeasurement.aidl b/android/app/aidl/android/bluetooth/IDistanceMeasurement.aidl
index 78c793a351..ead28c8ebd 100644
--- a/android/app/aidl/android/bluetooth/IDistanceMeasurement.aidl
+++ b/android/app/aidl/android/bluetooth/IDistanceMeasurement.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2025 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/android/app/aidl/android/bluetooth/IncomingRfcommSocketInfo.aidl b/android/app/aidl/android/bluetooth/IncomingRfcommSocketInfo.aidl
index 38ffe6f699..c3d542c774 100644
--- a/android/app/aidl/android/bluetooth/IncomingRfcommSocketInfo.aidl
+++ b/android/app/aidl/android/bluetooth/IncomingRfcommSocketInfo.aidl
@@ -5,7 +5,7 @@
* 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
+ * 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,
diff --git a/android/app/aidl/android/bluetooth/OobData.aidl b/android/app/aidl/android/bluetooth/OobData.aidl
index 529e0b0a42..d831c64776 100644
--- a/android/app/aidl/android/bluetooth/OobData.aidl
+++ b/android/app/aidl/android/bluetooth/OobData.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2016 The Android Open Source Project
+ * Copyright (C) 2016 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.
diff --git a/android/app/aidl/android/bluetooth/le/AdvertiseData.aidl b/android/app/aidl/android/bluetooth/le/AdvertiseData.aidl
index 713635d5ce..bcbf2243e1 100644
--- a/android/app/aidl/android/bluetooth/le/AdvertiseData.aidl
+++ b/android/app/aidl/android/bluetooth/le/AdvertiseData.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2014 The Android Open Source Project
+ * Copyright (C) 2014 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.
diff --git a/android/app/aidl/android/bluetooth/le/AdvertiseSettings.aidl b/android/app/aidl/android/bluetooth/le/AdvertiseSettings.aidl
index 3677e752e6..9f47d74ca5 100644
--- a/android/app/aidl/android/bluetooth/le/AdvertiseSettings.aidl
+++ b/android/app/aidl/android/bluetooth/le/AdvertiseSettings.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2014 The Android Open Source Project
+ * Copyright (C) 2014 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.
diff --git a/android/app/aidl/android/bluetooth/le/AdvertisingSetParameters.aidl b/android/app/aidl/android/bluetooth/le/AdvertisingSetParameters.aidl
index 3918864bd1..39034a001f 100644
--- a/android/app/aidl/android/bluetooth/le/AdvertisingSetParameters.aidl
+++ b/android/app/aidl/android/bluetooth/le/AdvertisingSetParameters.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2017 The Android Open Source Project
+ * Copyright (C) 2017 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.
diff --git a/android/app/aidl/android/bluetooth/le/DistanceMeasurementMethod.aidl b/android/app/aidl/android/bluetooth/le/DistanceMeasurementMethod.aidl
index ee341d30a0..08612dad3f 100644
--- a/android/app/aidl/android/bluetooth/le/DistanceMeasurementMethod.aidl
+++ b/android/app/aidl/android/bluetooth/le/DistanceMeasurementMethod.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/aidl/android/bluetooth/le/DistanceMeasurementParams.aidl b/android/app/aidl/android/bluetooth/le/DistanceMeasurementParams.aidl
index be0eba3606..19ec0c0379 100644
--- a/android/app/aidl/android/bluetooth/le/DistanceMeasurementParams.aidl
+++ b/android/app/aidl/android/bluetooth/le/DistanceMeasurementParams.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/aidl/android/bluetooth/le/DistanceMeasurementResult.aidl b/android/app/aidl/android/bluetooth/le/DistanceMeasurementResult.aidl
index eb4b0c84fa..dc4cfd9cda 100644
--- a/android/app/aidl/android/bluetooth/le/DistanceMeasurementResult.aidl
+++ b/android/app/aidl/android/bluetooth/le/DistanceMeasurementResult.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/aidl/android/bluetooth/le/IAdvertisingSetCallback.aidl b/android/app/aidl/android/bluetooth/le/IAdvertisingSetCallback.aidl
index 449b173309..b5d492905e 100644
--- a/android/app/aidl/android/bluetooth/le/IAdvertisingSetCallback.aidl
+++ b/android/app/aidl/android/bluetooth/le/IAdvertisingSetCallback.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2017 The Android Open Source Project
+ * Copyright (C) 2017 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.
diff --git a/android/app/aidl/android/bluetooth/le/IDistanceMeasurementCallback.aidl b/android/app/aidl/android/bluetooth/le/IDistanceMeasurementCallback.aidl
index 19f4ba72e5..518b0be4a6 100644
--- a/android/app/aidl/android/bluetooth/le/IDistanceMeasurementCallback.aidl
+++ b/android/app/aidl/android/bluetooth/le/IDistanceMeasurementCallback.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/aidl/android/bluetooth/le/IPeriodicAdvertisingCallback.aidl b/android/app/aidl/android/bluetooth/le/IPeriodicAdvertisingCallback.aidl
index 579ec086b7..b70b03f392 100644
--- a/android/app/aidl/android/bluetooth/le/IPeriodicAdvertisingCallback.aidl
+++ b/android/app/aidl/android/bluetooth/le/IPeriodicAdvertisingCallback.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2017 The Android Open Source Project
+ * Copyright (C) 2017 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.
diff --git a/android/app/aidl/android/bluetooth/le/IScannerCallback.aidl b/android/app/aidl/android/bluetooth/le/IScannerCallback.aidl
index 025e7ffbba..8cbbaef41a 100644
--- a/android/app/aidl/android/bluetooth/le/IScannerCallback.aidl
+++ b/android/app/aidl/android/bluetooth/le/IScannerCallback.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2016 The Android Open Source Project
+ * Copyright (C) 2016 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.
diff --git a/android/app/aidl/android/bluetooth/le/PeriodicAdvertisingParameters.aidl b/android/app/aidl/android/bluetooth/le/PeriodicAdvertisingParameters.aidl
index 3f714f0813..f4bea22a12 100644
--- a/android/app/aidl/android/bluetooth/le/PeriodicAdvertisingParameters.aidl
+++ b/android/app/aidl/android/bluetooth/le/PeriodicAdvertisingParameters.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2017 The Android Open Source Project
+ * Copyright (C) 2017 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.
diff --git a/android/app/aidl/android/bluetooth/le/PeriodicAdvertisingReport.aidl b/android/app/aidl/android/bluetooth/le/PeriodicAdvertisingReport.aidl
index 986ac6165c..547d09611f 100644
--- a/android/app/aidl/android/bluetooth/le/PeriodicAdvertisingReport.aidl
+++ b/android/app/aidl/android/bluetooth/le/PeriodicAdvertisingReport.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2017 The Android Open Source Project
+ * Copyright (C) 2017 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.
diff --git a/android/app/aidl/android/bluetooth/le/ResultStorageDescriptor.aidl b/android/app/aidl/android/bluetooth/le/ResultStorageDescriptor.aidl
index afc1b41fdf..f218a01a5d 100644
--- a/android/app/aidl/android/bluetooth/le/ResultStorageDescriptor.aidl
+++ b/android/app/aidl/android/bluetooth/le/ResultStorageDescriptor.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2014 The Android Open Source Project
+ * Copyright (C) 2014 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.
diff --git a/android/app/aidl/android/bluetooth/le/ScanFilter.aidl b/android/app/aidl/android/bluetooth/le/ScanFilter.aidl
index e3ebd857f4..4cecfe62e1 100644
--- a/android/app/aidl/android/bluetooth/le/ScanFilter.aidl
+++ b/android/app/aidl/android/bluetooth/le/ScanFilter.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2014 The Android Open Source Project
+ * Copyright (C) 2014 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.
diff --git a/android/app/aidl/android/bluetooth/le/ScanResult.aidl b/android/app/aidl/android/bluetooth/le/ScanResult.aidl
index f16dc18d43..39430350da 100644
--- a/android/app/aidl/android/bluetooth/le/ScanResult.aidl
+++ b/android/app/aidl/android/bluetooth/le/ScanResult.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2014 The Android Open Source Project
+ * Copyright (C) 2014 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.
diff --git a/android/app/aidl/android/bluetooth/le/ScanSettings.aidl b/android/app/aidl/android/bluetooth/le/ScanSettings.aidl
index e84e078ed0..eb169c1209 100644
--- a/android/app/aidl/android/bluetooth/le/ScanSettings.aidl
+++ b/android/app/aidl/android/bluetooth/le/ScanSettings.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2014 The Android Open Source Project
+ * Copyright (C) 2014 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.
diff --git a/android/app/jni/com_android_bluetooth_BluetoothHciVendorSpecific.cpp b/android/app/jni/com_android_bluetooth_BluetoothHciVendorSpecific.cpp
index 96c15300af..75cf1efea8 100644
--- a/android/app/jni/com_android_bluetooth_BluetoothHciVendorSpecific.cpp
+++ b/android/app/jni/com_android_bluetooth_BluetoothHciVendorSpecific.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 The Android Open Source Project
+ * Copyright (C) 2024 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.
diff --git a/android/app/jni/com_android_bluetooth_BluetoothQualityReport.cpp b/android/app/jni/com_android_bluetooth_BluetoothQualityReport.cpp
index b59bc9116f..8a225555b1 100644
--- a/android/app/jni/com_android_bluetooth_BluetoothQualityReport.cpp
+++ b/android/app/jni/com_android_bluetooth_BluetoothQualityReport.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 The Android Open Source Project
+ * Copyright (C) 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.
diff --git a/android/app/jni/com_android_bluetooth_btservice_BluetoothKeystore.cpp b/android/app/jni/com_android_bluetooth_btservice_BluetoothKeystore.cpp
index 5151bbff2f..b95ccf202d 100644
--- a/android/app/jni/com_android_bluetooth_btservice_BluetoothKeystore.cpp
+++ b/android/app/jni/com_android_bluetooth_btservice_BluetoothKeystore.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/android/app/jni/com_android_bluetooth_gatt.cpp b/android/app/jni/com_android_bluetooth_gatt.cpp
index acd609f8bd..be0922c8fc 100644
--- a/android/app/jni/com_android_bluetooth_gatt.cpp
+++ b/android/app/jni/com_android_bluetooth_gatt.cpp
@@ -2353,7 +2353,11 @@ static AdvertiseParameters parseParams(JNIEnv* env, jobject i) {
p.secondary_advertising_phy = secondaryPhy;
p.scan_request_notification_enable = false;
p.own_address_type = ownAddressType;
- p.peer_address = str2addr(env, peerAddress);
+ if (peerAddress == nullptr) {
+ p.peer_address = RawAddress::kEmpty;
+ } else {
+ p.peer_address = str2addr(env, peerAddress);
+ }
p.peer_address_type = peerAddressType;
p.discoverable = isDiscoverable;
return p;
diff --git a/android/app/jni/com_android_bluetooth_hearing_aid.cpp b/android/app/jni/com_android_bluetooth_hearing_aid.cpp
index dbe2439ed4..312961db41 100644
--- a/android/app/jni/com_android_bluetooth_hearing_aid.cpp
+++ b/android/app/jni/com_android_bluetooth_hearing_aid.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 The Android Open Source Project
+ * Copyright (C) 2018 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.
diff --git a/android/app/jni/com_android_bluetooth_hfp.cpp b/android/app/jni/com_android_bluetooth_hfp.cpp
index 18a0bf1950..f321497e16 100644
--- a/android/app/jni/com_android_bluetooth_hfp.cpp
+++ b/android/app/jni/com_android_bluetooth_hfp.cpp
@@ -651,7 +651,8 @@ static jboolean isVoiceRecognitionSupportedNative(JNIEnv* env, jobject /* object
return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
}
-static jboolean startVoiceRecognitionNative(JNIEnv* env, jobject /* object */, jbyteArray address) {
+static jboolean startVoiceRecognitionNative(JNIEnv* env, jobject /* object */, jbyteArray address,
+ jboolean sendResult) {
std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
if (!sBluetoothHfpInterface) {
log::warn("sBluetoothHfpInterface is null");
@@ -663,7 +664,7 @@ static jboolean startVoiceRecognitionNative(JNIEnv* env, jobject /* object */, j
jniThrowIOException(env, EINVAL);
return JNI_FALSE;
}
- bt_status_t status = sBluetoothHfpInterface->StartVoiceRecognition((RawAddress*)addr);
+ bt_status_t status = sBluetoothHfpInterface->StartVoiceRecognition((RawAddress*)addr, sendResult);
if (status != BT_STATUS_SUCCESS) {
log::error("Failed to start voice recognition, status: {}", bt_status_text(status));
}
@@ -986,7 +987,7 @@ int register_com_android_bluetooth_hfp(JNIEnv* env) {
{"disconnectAudioNative", "([B)Z", (void*)disconnectAudioNative},
{"isNoiseReductionSupportedNative", "([B)Z", (void*)isNoiseReductionSupportedNative},
{"isVoiceRecognitionSupportedNative", "([B)Z", (void*)isVoiceRecognitionSupportedNative},
- {"startVoiceRecognitionNative", "([B)Z", (void*)startVoiceRecognitionNative},
+ {"startVoiceRecognitionNative", "([BZ)Z", (void*)startVoiceRecognitionNative},
{"stopVoiceRecognitionNative", "([B)Z", (void*)stopVoiceRecognitionNative},
{"setVolumeNative", "(II[B)Z", (void*)setVolumeNative},
{"notifyDeviceStatusNative", "(IIII[B)Z", (void*)notifyDeviceStatusNative},
diff --git a/android/app/lib-lint-baseline.xml b/android/app/lib-lint-baseline.xml
index c2a527c3fc..ac5565be67 100644
--- a/android/app/lib-lint-baseline.xml
+++ b/android/app/lib-lint-baseline.xml
@@ -2,17 +2,6 @@
<issues format="6" by="lint 8.4.0-alpha08" type="baseline" client="" dependencies="true" name="" variant="all" version="8.4.0-alpha08">
<issue
- id="UnknownIssueId"
- message="Unknown issue id &quot;GetterSetterNullability&quot;"
- errorLine1=" &lt;issue id=&apos;GetterSetterNullability&apos; severity=&apos;error&apos; />"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="./out/lint.xml"
- line="125"
- column="3"/>
- </issue>
-
- <issue
id="GestureBackNavigation"
message="If intercepting back events, this should be handled through the registration of callbacks on the window level; Please see https://developer.android.com/about/versions/13/features/predictive-back-gesture"
errorLine1=" if (keyCode == KeyEvent.KEYCODE_BACK) {"
@@ -68,332 +57,13 @@
</issue>
<issue
- id="DefaultLocale"
- message="Implicitly using the default locale is a common source of bugs: Use `String.format(Locale, ...)` instead"
- errorLine1=" String.format("
- errorLine2=" ^">
- <location
- file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/avrcp/AvrcpVolumeManager.java"
- line="460"
- column="25"/>
- </issue>
-
- <issue
- id="DefaultLocale"
- message="Implicitly using the default locale is a common source of bugs: Use `String.format(Locale, ...)` instead"
- errorLine1=" offsetString = String.format(&quot;%1$02d&quot;, -(offset));"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/map/BluetoothMapSmsPdu.java"
- line="403"
- column="32"/>
- </issue>
-
- <issue
- id="DefaultLocale"
- message="Implicitly using the default locale is a common source of bugs: Use `String.format(Locale, ...)` instead"
- errorLine1=" offsetString = String.format(&quot;%1$02d&quot;, offset);"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/map/BluetoothMapSmsPdu.java"
- line="407"
- column="32"/>
- </issue>
-
- <issue
- id="DefaultLocale"
- message="Implicitly using the default locale is a common source of bugs: Use `String.format(Locale, ...)` instead"
- errorLine1=" return String.format("
- errorLine2=" ^">
- <location
- file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/mapclient/MapClientContent.java"
- line="911"
- column="20"/>
- </issue>
-
- <issue
- id="SimpleDateFormat"
- message="To get local formatting use `getDateInstance()`, `getDateTimeInstance()`, or `getTimeInstance()`, or use `new SimpleDateFormat(String template, Locale locale)` with for example `Locale.US` for ASCII dates."
- errorLine1=" ThreadLocal.withInitial(() -> new SimpleDateFormat(&quot;MM-dd HH:mm:ss&quot;));"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/le_scan/AppScanStats.java"
- line="53"
- column="43"/>
- </issue>
-
- <issue
- id="SimpleDateFormat"
- message="To get local formatting use `getDateInstance()`, `getDateTimeInstance()`, or `getTimeInstance()`, or use `new SimpleDateFormat(String template, Locale locale)` with for example `Locale.US` for ASCII dates."
- errorLine1=" SimpleDateFormat format = new SimpleDateFormat(&quot;yyyyMMdd&apos;T&apos;HHmmss&quot;);"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/map/BluetoothMapAppParams.java"
- line="1228"
- column="35"/>
- </issue>
-
- <issue
- id="SimpleDateFormat"
- message="To get local formatting use `getDateInstance()`, `getDateTimeInstance()`, or `getTimeInstance()`, or use `new SimpleDateFormat(String template, Locale locale)` with for example `Locale.US` for ASCII dates."
- errorLine1=" SimpleDateFormat format = new SimpleDateFormat(&quot;yyyyMMdd&apos;T&apos;HHmmss&quot;);"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/map/BluetoothMapAppParams.java"
- line="1239"
- column="35"/>
- </issue>
-
- <issue
- id="SimpleDateFormat"
- message="To get local formatting use `getDateInstance()`, `getDateTimeInstance()`, or `getTimeInstance()`, or use `new SimpleDateFormat(String template, Locale locale)` with for example `Locale.US` for ASCII dates."
- errorLine1=" SimpleDateFormat format = new SimpleDateFormat(&quot;yyyyMMdd&apos;T&apos;HHmmss&quot;);"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/map/BluetoothMapAppParams.java"
- line="1250"
- column="35"/>
- </issue>
-
- <issue
- id="SimpleDateFormat"
- message="To get local formatting use `getDateInstance()`, `getDateTimeInstance()`, or `getTimeInstance()`, or use `new SimpleDateFormat(String template, Locale locale)` with for example `Locale.US` for ASCII dates."
- errorLine1=" SimpleDateFormat format = new SimpleDateFormat(&quot;yyyyMMdd&apos;T&apos;HHmmss&quot;);"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/map/BluetoothMapAppParams.java"
- line="1261"
- column="35"/>
- </issue>
-
- <issue
- id="SimpleDateFormat"
- message="To get local formatting use `getDateInstance()`, `getDateTimeInstance()`, or `getTimeInstance()`, or use `new SimpleDateFormat(String template, Locale locale)` with for example `Locale.US` for ASCII dates."
- errorLine1=" SimpleDateFormat format = new SimpleDateFormat(&quot;yyyyMMdd&apos;T&apos;HHmmss&quot;);"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/map/BluetoothMapAppParams.java"
- line="1276"
- column="35"/>
- </issue>
-
- <issue
- id="SimpleDateFormat"
- message="To get local formatting use `getDateInstance()`, `getDateTimeInstance()`, or `getTimeInstance()`, or use `new SimpleDateFormat(String template, Locale locale)` with for example `Locale.US` for ASCII dates."
- errorLine1=" SimpleDateFormat format = new SimpleDateFormat(&quot;yyyyMMdd&apos;T&apos;HHmmss&quot;);"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/map/BluetoothMapAppParams.java"
- line="1287"
- column="35"/>
- </issue>
-
- <issue
- id="SimpleDateFormat"
- message="To get local formatting use `getDateInstance()`, `getDateTimeInstance()`, or `getTimeInstance()`, or use `new SimpleDateFormat(String template, Locale locale)` with for example `Locale.US` for ASCII dates."
- errorLine1=" SimpleDateFormat format = new SimpleDateFormat(&quot;yyyyMMdd&apos;T&apos;HHmmss&quot;);"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/map/BluetoothMapAppParams.java"
- line="1294"
- column="35"/>
- </issue>
-
- <issue
- id="SimpleDateFormat"
- message="To get local formatting use `getDateInstance()`, `getDateTimeInstance()`, or `getTimeInstance()`, or use `new SimpleDateFormat(String template, Locale locale)` with for example `Locale.US` for ASCII dates."
- errorLine1=" SimpleDateFormat format = new SimpleDateFormat(&quot;yyyyMMdd&apos;T&apos;HHmmss&quot;);"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/map/BluetoothMapAppParams.java"
- line="1305"
- column="35"/>
- </issue>
-
- <issue
- id="SimpleDateFormat"
- message="To get local formatting use `getDateInstance()`, `getDateTimeInstance()`, or `getTimeInstance()`, or use `new SimpleDateFormat(String template, Locale locale)` with for example `Locale.US` for ASCII dates."
- errorLine1=" SimpleDateFormat format = new SimpleDateFormat(&quot;yyyyMMdd&apos;T&apos;HHmmssZ&quot;);"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/map/BluetoothMapAppParams.java"
- line="1510"
- column="35"/>
- </issue>
-
- <issue
- id="SimpleDateFormat"
- message="To get local formatting use `getDateInstance()`, `getDateTimeInstance()`, or `getTimeInstance()`, or use `new SimpleDateFormat(String template, Locale locale)` with for example `Locale.US` for ASCII dates."
- errorLine1=" SimpleDateFormat format = new SimpleDateFormat(&quot;yyyyMMdd&apos;T&apos;HHmmssZ&quot;);"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/map/BluetoothMapAppParams.java"
- line="1521"
- column="35"/>
- </issue>
-
- <issue
- id="SimpleDateFormat"
- message="To get local formatting use `getDateInstance()`, `getDateTimeInstance()`, or `getTimeInstance()`, or use `new SimpleDateFormat(String template, Locale locale)` with for example `Locale.US` for ASCII dates."
- errorLine1=" SimpleDateFormat format = new SimpleDateFormat(&quot;yyyyMMdd&apos;T&apos;HHmmssZ&quot;);"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/map/BluetoothMapAppParams.java"
- line="1758"
- column="35"/>
- </issue>
-
- <issue
- id="SimpleDateFormat"
- message="To get local formatting use `getDateInstance()`, `getDateTimeInstance()`, or `getTimeInstance()`, or use `new SimpleDateFormat(String template, Locale locale)` with for example `Locale.US` for ASCII dates."
- errorLine1=" SimpleDateFormat format = new SimpleDateFormat(&quot;yyyyMMdd&apos;T&apos;HHmmssZ&quot;);"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/map/BluetoothMapAppParams.java"
- line="1769"
- column="35"/>
- </issue>
-
- <issue
- id="SimpleDateFormat"
- message="To get local formatting use `getDateInstance()`, `getDateTimeInstance()`, or `getTimeInstance()`, or use `new SimpleDateFormat(String template, Locale locale)` with for example `Locale.US` for ASCII dates."
- errorLine1=" SimpleDateFormat format = new SimpleDateFormat(&quot;yyyyMMdd&apos;T&apos;HHmmss&quot;);"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/map/BluetoothMapConvoContactElement.java"
- line="161"
- column="35"/>
- </issue>
-
- <issue
- id="SimpleDateFormat"
- message="To get local formatting use `getDateInstance()`, `getDateTimeInstance()`, or `getTimeInstance()`, or use `new SimpleDateFormat(String template, Locale locale)` with for example `Locale.US` for ASCII dates."
- errorLine1=" SimpleDateFormat format = new SimpleDateFormat(&quot;yyyyMMdd&apos;T&apos;HHmmss&quot;);"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/map/BluetoothMapConvoContactElement.java"
- line="172"
- column="35"/>
- </issue>
-
- <issue
- id="SimpleDateFormat"
- message="To get local formatting use `getDateInstance()`, `getDateTimeInstance()`, or `getTimeInstance()`, or use `new SimpleDateFormat(String template, Locale locale)` with for example `Locale.US` for ASCII dates."
- errorLine1=" SimpleDateFormat format = new SimpleDateFormat(&quot;yyyyMMdd&apos;T&apos;HHmmss&quot;);"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/map/BluetoothMapConvoListingElement.java"
- line="149"
- column="35"/>
- </issue>
-
- <issue
- id="SimpleDateFormat"
- message="To get local formatting use `getDateInstance()`, `getDateTimeInstance()`, or `getTimeInstance()`, or use `new SimpleDateFormat(String template, Locale locale)` with for example `Locale.US` for ASCII dates."
- errorLine1=" SimpleDateFormat format = new SimpleDateFormat(&quot;yyyyMMdd&apos;T&apos;HHmmss&quot;);"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/map/BluetoothMapConvoListingElement.java"
- line="162"
- column="35"/>
- </issue>
-
- <issue
- id="SimpleDateFormat"
- message="To get local formatting use `getDateInstance()`, `getDateTimeInstance()`, or `getTimeInstance()`, or use `new SimpleDateFormat(String template, Locale locale)` with for example `Locale.US` for ASCII dates."
- errorLine1=" SimpleDateFormat format = new SimpleDateFormat(&quot;yyyyMMdd&apos;T&apos;HHmmss&quot;);"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/map/BluetoothMapMessageListingElement.java"
- line="81"
- column="35"/>
- </issue>
-
- <issue
- id="SimpleDateFormat"
- message="To get local formatting use `getDateInstance()`, `getDateTimeInstance()`, or `getTimeInstance()`, or use `new SimpleDateFormat(String template, Locale locale)` with for example `Locale.US` for ASCII dates."
- errorLine1=" SimpleDateFormat format = new SimpleDateFormat(&quot;yyMMddHHmmss&quot;);"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/map/BluetoothMapSmsPdu.java"
- line="385"
- column="39"/>
- </issue>
-
- <issue
- id="SimpleDateFormat"
- message="To get local formatting use `getDateInstance()`, `getDateTimeInstance()`, or `getTimeInstance()`, or use `new SimpleDateFormat(String template, Locale locale)` with for example `Locale.US` for ASCII dates."
- errorLine1=" ? new SimpleDateFormat(&quot;yyyyMMdd&apos;T&apos;HHmmssZ&quot;)"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/map/BluetoothMapUtils.java"
- line="740"
- column="27"/>
- </issue>
-
- <issue
- id="SimpleDateFormat"
- message="To get local formatting use `getDateInstance()`, `getDateTimeInstance()`, or `getTimeInstance()`, or use `new SimpleDateFormat(String template, Locale locale)` with for example `Locale.US` for ASCII dates."
- errorLine1=" : new SimpleDateFormat(&quot;yyyyMMdd&apos;T&apos;HHmmss&quot;);"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/map/BluetoothMapUtils.java"
- line="741"
- column="27"/>
- </issue>
-
- <issue
- id="SimpleDateFormat"
- message="To get local formatting use `getDateInstance()`, `getDateTimeInstance()`, or `getTimeInstance()`, or use `new SimpleDateFormat(String template, Locale locale)` with for example `Locale.US` for ASCII dates."
- errorLine1=" DateFormat dateFormat = new SimpleDateFormat(&quot;_hhmmss&quot;);"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/opp/BluetoothOppReceiveFileInfo.java"
- line="167"
- column="33"/>
- </issue>
-
- <issue
- id="SimpleDateFormat"
- message="To get local formatting use `getDateInstance()`, `getDateTimeInstance()`, or `getTimeInstance()`, or use `new SimpleDateFormat(String template, Locale locale)` with for example `Locale.US` for ASCII dates."
- errorLine1=" SimpleDateFormat df = new SimpleDateFormat(RFC_2455_FORMAT);"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/pbap/BluetoothPbapCallLogComposer.java"
- line="226"
- column="31"/>
- </issue>
-
- <issue
- id="SimpleDateFormat"
- message="To get local formatting use `getDateInstance()`, `getDateTimeInstance()`, or `getTimeInstance()`, or use `new SimpleDateFormat(String template, Locale locale)` with for example `Locale.US` for ASCII dates."
- errorLine1=" SimpleDateFormat parser = new SimpleDateFormat(TIMESTAMP_FORMAT);"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/pbapclient/obex/CallLogPullRequest.java"
- line="109"
- column="43"/>
- </issue>
-
- <issue
- id="SimpleDateFormat"
- message="To get local formatting use `getDateInstance()`, `getDateTimeInstance()`, or `getTimeInstance()`, or use `new SimpleDateFormat(String template, Locale locale)` with for example `Locale.US` for ASCII dates."
- errorLine1=" SimpleDateFormat parser = new SimpleDateFormat(TIMESTAMP_FORMAT);"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/pbapclient/PbapClientContactsStorage.java"
- line="508"
- column="35"/>
- </issue>
-
- <issue
id="GuardedLogInvocation"
message="Do not guard log invocations with if blocks using log enforcement variables or isLoggable(). The Log framework does this check for you. Remove the surrounding if block and call to log completely unguarded"
errorLine1=" if (Log.isLoggable(TAG, Log.DEBUG)) {"
errorLine2=" ^">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/a2dp/A2dpStateMachine.java"
- line="679"
+ line="677"
column="9"/>
</issue>
@@ -404,7 +74,7 @@
errorLine2=" ^">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/a2dp/A2dpStateMachine.java"
- line="679"
+ line="677"
column="9"/>
</issue>
@@ -415,7 +85,7 @@
errorLine2=" ^">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/a2dp/A2dpStateMachine.java"
- line="679"
+ line="677"
column="9"/>
</issue>
@@ -426,7 +96,7 @@
errorLine2=" ^">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/map/BluetoothMapService.java"
- line="807"
+ line="805"
column="9"/>
</issue>
@@ -437,7 +107,7 @@
errorLine2=" ^">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/map/BluetoothMapService.java"
- line="807"
+ line="805"
column="9"/>
</issue>
@@ -448,7 +118,7 @@
errorLine2=" ^">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/map/BluetoothMapService.java"
- line="807"
+ line="805"
column="9"/>
</issue>
@@ -459,7 +129,7 @@
errorLine2=" ^">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/map/BluetoothMapService.java"
- line="807"
+ line="805"
column="9"/>
</issue>
@@ -547,7 +217,7 @@
errorLine2=" ~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/opp/BluetoothOppTransferActivity.java"
- line="240"
+ line="239"
column="69"/>
</issue>
@@ -565,154 +235,11 @@
<issue
id="VisibleForTests"
message="This method should only be accessed from tests or within private scope"
- errorLine1=" return mDatabaseManager.getA2dpSupportsOptionalCodecs(device);"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/a2dp/A2dpService.java"
- line="802"
- column="33"/>
- </issue>
-
- <issue
- id="VisibleForTests"
- message="This method should only be accessed from tests or within private scope"
- errorLine1=" mDatabaseManager.setA2dpSupportsOptionalCodecs(device, value);"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/a2dp/A2dpService.java"
- line="810"
- column="26"/>
- </issue>
-
- <issue
- id="VisibleForTests"
- message="This method should only be accessed from tests or within private scope"
- errorLine1=" return mDatabaseManager.getA2dpOptionalCodecsEnabled(device);"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/a2dp/A2dpService.java"
- line="823"
- column="33"/>
- </issue>
-
- <issue
- id="VisibleForTests"
- message="This method should only be accessed from tests or within private scope"
- errorLine1=" mDatabaseManager.setA2dpOptionalCodecsEnabled(device, value);"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/a2dp/A2dpService.java"
- line="843"
- column="26"/>
- </issue>
-
- <issue
- id="VisibleForTests"
- message="This method should only be accessed from tests or within private scope"
- errorLine1=" sm.sendMessage(A2dpStateMachine.MESSAGE_STACK_EVENT, stackEvent);"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~">
- <location
- file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/a2dp/A2dpService.java"
- line="918"
- column="45"/>
- </issue>
-
- <issue
- id="VisibleForTests"
- message="This method should only be accessed from tests or within private scope"
- errorLine1=" Config.setProfileEnabled(BluetoothProfile.LE_AUDIO_BROADCAST, false);"
- errorLine2=" ~~~~~~~~~~~~~~~~~">
- <location
- file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/btservice/AdapterService.java"
- line="1149"
- column="20"/>
- </issue>
-
- <issue
- id="VisibleForTests"
- message="This method should only be accessed from tests or within private scope"
- errorLine1=" Config.setProfileEnabled(profileId, false);"
- errorLine2=" ~~~~~~~~~~~~~~~~~">
- <location
- file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/btservice/AdapterService.java"
- line="1154"
- column="20"/>
- </issue>
-
- <issue
- id="VisibleForTests"
- message="This method should only be accessed from tests or within private scope"
- errorLine1=" mMapService = BluetoothMapService.getBluetoothMapService();"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/btservice/AdapterService.java"
- line="1996"
- column="43"/>
- </issue>
-
- <issue
- id="VisibleForTests"
- message="This method should only be accessed from tests or within private scope"
- errorLine1=" mPbapService = BluetoothPbapService.getBluetoothPbapService();"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/btservice/AdapterService.java"
- line="2001"
- column="45"/>
- </issue>
-
- <issue
- id="VisibleForTests"
- message="This method should only be accessed from tests or within private scope"
- errorLine1=" mSapService = SapService.getSapService();"
- errorLine2=" ~~~~~~~~~~~~~">
- <location
- file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/btservice/AdapterService.java"
- line="2005"
- column="34"/>
- </issue>
-
- <issue
- id="VisibleForTests"
- message="This method should only be accessed from tests or within private scope"
- errorLine1=" return mDatabaseManager.setCustomMeta(device, key, value);"
- errorLine2=" ~~~~~~~~~~~~~">
- <location
- file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/btservice/AdapterService.java"
- line="2237"
- column="33"/>
- </issue>
-
- <issue
- id="VisibleForTests"
- message="This method should only be accessed from tests or within private scope"
- errorLine1=" mRemoteDevices.resetBatteryLevel(device, isBas);"
- errorLine2=" ~~~~~~~~~~~~~~~~~">
- <location
- file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/btservice/AdapterService.java"
- line="7293"
- column="28"/>
- </issue>
-
- <issue
- id="VisibleForTests"
- message="This method should only be accessed from tests or within private scope"
- errorLine1=" mRemoteDevices.updateBatteryLevel(device, batteryLevel, isBas);"
- errorLine2=" ~~~~~~~~~~~~~~~~~~">
- <location
- file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/btservice/AdapterService.java"
- line="7295"
- column="28"/>
- </issue>
-
- <issue
- id="VisibleForTests"
- message="This method should only be accessed from tests or within private scope"
errorLine1=" mNativeInterface.atResponseCode(device, atCommandResult, atCommandErrorCode);"
errorLine2=" ~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/AtPhonebook.java"
- line="182"
+ line="187"
column="38"/>
</issue>
@@ -723,7 +250,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/AtPhonebook.java"
- line="203"
+ line="208"
column="30"/>
</issue>
@@ -734,7 +261,7 @@
errorLine2=" ~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/AtPhonebook.java"
- line="205"
+ line="210"
column="26"/>
</issue>
@@ -745,7 +272,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/AtPhonebook.java"
- line="274"
+ line="279"
column="30"/>
</issue>
@@ -756,7 +283,7 @@
errorLine2=" ~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/AtPhonebook.java"
- line="276"
+ line="281"
column="26"/>
</issue>
@@ -767,7 +294,7 @@
errorLine2=" ~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/AtPhonebook.java"
- line="299"
+ line="304"
column="42"/>
</issue>
@@ -778,7 +305,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/AtPhonebook.java"
- line="314"
+ line="319"
column="34"/>
</issue>
@@ -789,7 +316,7 @@
errorLine2=" ~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/AtPhonebook.java"
- line="315"
+ line="320"
column="34"/>
</issue>
@@ -800,7 +327,7 @@
errorLine2=" ~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/AtPhonebook.java"
- line="326"
+ line="331"
column="38"/>
</issue>
@@ -811,7 +338,7 @@
errorLine2=" ~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/AtPhonebook.java"
- line="334"
+ line="339"
column="38"/>
</issue>
@@ -822,7 +349,7 @@
errorLine2=" ~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/AtPhonebook.java"
- line="354"
+ line="359"
column="38"/>
</issue>
@@ -833,7 +360,7 @@
errorLine2=" ~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/AtPhonebook.java"
- line="367"
+ line="372"
column="38"/>
</issue>
@@ -844,7 +371,7 @@
errorLine2=" ~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/AtPhonebook.java"
- line="373"
+ line="378"
column="38"/>
</issue>
@@ -855,7 +382,7 @@
errorLine2=" ~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/AtPhonebook.java"
- line="387"
+ line="392"
column="34"/>
</issue>
@@ -866,7 +393,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/AtPhonebook.java"
- line="640"
+ line="645"
column="30"/>
</issue>
@@ -1016,66 +543,11 @@
<issue
id="VisibleForTests"
message="This method should only be accessed from tests or within private scope"
- errorLine1=" BluetoothMapService.getBluetoothMapService()"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/map/BluetoothMapContent.java"
- line="1261"
- column="49"/>
- </issue>
-
- <issue
- id="VisibleForTests"
- message="This method should only be accessed from tests or within private scope"
- errorLine1=" BluetoothMapService.getBluetoothMapService()"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/map/BluetoothMapMessageListing.java"
- line="104"
- column="49"/>
- </issue>
-
- <issue
- id="VisibleForTests"
- message="This method should only be accessed from tests or within private scope"
- errorLine1=" BluetoothMapService.getBluetoothMapService().getRemoteDevice().getAddress(),"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/map/BluetoothMapMessageListing.java"
- line="153"
- column="45"/>
- </issue>
-
- <issue
- id="VisibleForTests"
- message="This method should only be accessed from tests or within private scope"
- errorLine1=" BluetoothMapService.getBluetoothMapService().getRemoteDevice().getAddress(),"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/map/BluetoothMapMessageListingElement.java"
- line="276"
- column="41"/>
- </issue>
-
- <issue
- id="VisibleForTests"
- message="This method should only be accessed from tests or within private scope"
- errorLine1=" BluetoothMapService.getBluetoothMapService().getRemoteDevice().getAddress();"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/map/BluetoothMapbMessageSms.java"
- line="93"
- column="41"/>
- </issue>
-
- <issue
- id="VisibleForTests"
- message="This method should only be accessed from tests or within private scope"
errorLine1=" mRemoteDevices.addDeviceProperties(address);"
errorLine2=" ~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/btservice/BondStateMachine.java"
- line="656"
+ line="657"
column="28"/>
</issue>
@@ -1086,7 +558,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/btservice/BondStateMachine.java"
- line="693"
+ line="694"
column="28"/>
</issue>
@@ -1097,7 +569,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/btservice/BondStateMachine.java"
- line="723"
+ line="724"
column="28"/>
</issue>
@@ -1108,7 +580,7 @@
errorLine2=" ~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/csip/CsipSetCoordinatorService.java"
- line="855"
+ line="860"
column="63"/>
</issue>
@@ -1119,7 +591,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hap/HapClientService.java"
- line="157"
+ line="162"
column="16"/>
</issue>
@@ -1130,7 +602,7 @@
errorLine2=" ~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientService.java"
- line="105"
+ line="111"
column="26"/>
</issue>
@@ -1141,7 +613,7 @@
errorLine2=" ~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientService.java"
- line="177"
+ line="183"
column="26"/>
</issue>
@@ -1152,7 +624,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java"
- line="418"
+ line="423"
column="26"/>
</issue>
@@ -1163,7 +635,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java"
- line="671"
+ line="676"
column="30"/>
</issue>
@@ -1174,7 +646,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java"
- line="712"
+ line="717"
column="30"/>
</issue>
@@ -1185,7 +657,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java"
- line="737"
+ line="742"
column="30"/>
</issue>
@@ -1196,7 +668,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java"
- line="760"
+ line="765"
column="34"/>
</issue>
@@ -1207,7 +679,7 @@
errorLine2=" ~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java"
- line="1008"
+ line="1013"
column="30"/>
</issue>
@@ -1218,7 +690,7 @@
errorLine2=" ~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java"
- line="1098"
+ line="1095"
column="43"/>
</issue>
@@ -1229,7 +701,7 @@
errorLine2=" ~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java"
- line="1152"
+ line="1146"
column="42"/>
</issue>
@@ -1240,7 +712,7 @@
errorLine2=" ~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java"
- line="1316"
+ line="1304"
column="42"/>
</issue>
@@ -1251,7 +723,7 @@
errorLine2=" ~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java"
- line="1324"
+ line="1312"
column="46"/>
</issue>
@@ -1262,7 +734,7 @@
errorLine2=" ~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java"
- line="1435"
+ line="1413"
column="38"/>
</issue>
@@ -1273,7 +745,7 @@
errorLine2=" ~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java"
- line="1443"
+ line="1421"
column="47"/>
</issue>
@@ -1284,7 +756,7 @@
errorLine2=" ~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java"
- line="1447"
+ line="1425"
column="50"/>
</issue>
@@ -1295,7 +767,7 @@
errorLine2=" ~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java"
- line="1453"
+ line="1431"
column="43"/>
</issue>
@@ -1306,7 +778,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java"
- line="1473"
+ line="1451"
column="46"/>
</issue>
@@ -1317,7 +789,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java"
- line="1483"
+ line="1461"
column="46"/>
</issue>
@@ -1328,7 +800,7 @@
errorLine2=" ~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java"
- line="1505"
+ line="1483"
column="46"/>
</issue>
@@ -1339,7 +811,7 @@
errorLine2=" ~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java"
- line="1526"
+ line="1504"
column="46"/>
</issue>
@@ -1350,7 +822,7 @@
errorLine2=" ~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java"
- line="1537"
+ line="1515"
column="42"/>
</issue>
@@ -1361,7 +833,7 @@
errorLine2=" ~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java"
- line="1568"
+ line="1546"
column="42"/>
</issue>
@@ -1372,7 +844,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java"
- line="1575"
+ line="1553"
column="42"/>
</issue>
@@ -1383,7 +855,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java"
- line="1641"
+ line="1619"
column="54"/>
</issue>
@@ -1394,7 +866,7 @@
errorLine2=" ~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java"
- line="2544"
+ line="2519"
column="31"/>
</issue>
@@ -1405,7 +877,7 @@
errorLine2=" ~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java"
- line="2554"
+ line="2529"
column="31"/>
</issue>
@@ -1427,7 +899,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetService.java"
- line="273"
+ line="277"
column="38"/>
</issue>
@@ -1438,7 +910,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetService.java"
- line="275"
+ line="279"
column="42"/>
</issue>
@@ -1449,7 +921,7 @@
errorLine2=" ~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetService.java"
- line="288"
+ line="292"
column="26"/>
</issue>
@@ -1460,18 +932,18 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetService.java"
- line="436"
+ line="440"
column="42"/>
</issue>
<issue
id="VisibleForTests"
message="This method should only be accessed from tests or within private scope"
- errorLine1=" if (stateMachine.getConnectionState() != BluetoothProfile.STATE_DISCONNECTED) {"
+ errorLine1=" if (stateMachine.getConnectionState() != STATE_DISCONNECTED) {"
errorLine2=" ~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetService.java"
- line="508"
+ line="512"
column="30"/>
</issue>
@@ -1482,7 +954,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetService.java"
- line="866"
+ line="870"
column="48"/>
</issue>
@@ -1493,18 +965,18 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetService.java"
- line="914"
+ line="917"
column="48"/>
</issue>
<issue
id="VisibleForTests"
message="This method should only be accessed from tests or within private scope"
- errorLine1=" if (stateMachine.getConnectionState() == BluetoothProfile.STATE_CONNECTED) {"
+ errorLine1=" if (stateMachine.getConnectionState() == STATE_CONNECTED) {"
errorLine2=" ~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetService.java"
- line="934"
+ line="936"
column="34"/>
</issue>
@@ -1515,7 +987,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetService.java"
- line="982"
+ line="984"
column="33"/>
</issue>
@@ -1526,7 +998,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetService.java"
- line="1096"
+ line="1098"
column="38"/>
</issue>
@@ -1537,7 +1009,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetService.java"
- line="1098"
+ line="1100"
column="42"/>
</issue>
@@ -1548,7 +1020,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetService.java"
- line="1114"
+ line="1116"
column="48"/>
</issue>
@@ -1559,7 +1031,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetService.java"
- line="1188"
+ line="1200"
column="48"/>
</issue>
@@ -1570,7 +1042,7 @@
errorLine2=" ~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetService.java"
- line="1243"
+ line="1265"
column="26"/>
</issue>
@@ -1581,7 +1053,7 @@
errorLine2=" ~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetService.java"
- line="1379"
+ line="1401"
column="30"/>
</issue>
@@ -1592,7 +1064,7 @@
errorLine2=" ~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetService.java"
- line="1422"
+ line="1444"
column="35"/>
</issue>
@@ -1603,7 +1075,7 @@
errorLine2=" ~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetService.java"
- line="1433"
+ line="1455"
column="65"/>
</issue>
@@ -1614,7 +1086,7 @@
errorLine2=" ~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetService.java"
- line="1451"
+ line="1473"
column="38"/>
</issue>
@@ -1625,18 +1097,18 @@
errorLine2=" ~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetService.java"
- line="1490"
+ line="1512"
column="42"/>
</issue>
<issue
id="VisibleForTests"
message="This method should only be accessed from tests or within private scope"
- errorLine1=" if (stateMachine.getConnectionState() != BluetoothProfile.STATE_CONNECTED) {"
+ errorLine1=" if (stateMachine.getConnectionState() != STATE_CONNECTED) {"
errorLine2=" ~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetService.java"
- line="1549"
+ line="1571"
column="30"/>
</issue>
@@ -1647,7 +1119,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetService.java"
- line="1784"
+ line="1831"
column="38"/>
</issue>
@@ -1658,7 +1130,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetService.java"
- line="1786"
+ line="1833"
column="42"/>
</issue>
@@ -1669,7 +1141,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetService.java"
- line="1868"
+ line="1920"
column="35"/>
</issue>
@@ -1680,7 +1152,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetService.java"
- line="1881"
+ line="1933"
column="35"/>
</issue>
@@ -1691,7 +1163,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetService.java"
- line="1882"
+ line="1934"
column="34"/>
</issue>
@@ -1702,7 +1174,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetService.java"
- line="1909"
+ line="1966"
column="38"/>
</issue>
@@ -1713,7 +1185,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetService.java"
- line="1911"
+ line="1968"
column="42"/>
</issue>
@@ -1724,7 +1196,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetService.java"
- line="1932"
+ line="1989"
column="35"/>
</issue>
@@ -1735,7 +1207,7 @@
errorLine2=" ~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetService.java"
- line="1984"
+ line="2046"
column="65"/>
</issue>
@@ -1746,7 +1218,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetService.java"
- line="1985"
+ line="2047"
column="38"/>
</issue>
@@ -1757,7 +1229,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetService.java"
- line="1986"
+ line="2048"
column="38"/>
</issue>
@@ -1768,7 +1240,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetService.java"
- line="1987"
+ line="2049"
column="38"/>
</issue>
@@ -1779,7 +1251,7 @@
errorLine2=" ~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetService.java"
- line="1991"
+ line="2058"
column="50"/>
</issue>
@@ -1790,7 +1262,7 @@
errorLine2=" ~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetService.java"
- line="2009"
+ line="2076"
column="49"/>
</issue>
@@ -1801,7 +1273,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetService.java"
- line="2078"
+ line="2149"
column="48"/>
</issue>
@@ -1812,7 +1284,7 @@
errorLine2=" ~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetService.java"
- line="2226"
+ line="2294"
column="86"/>
</issue>
@@ -1823,7 +1295,7 @@
errorLine2=" ~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetService.java"
- line="2234"
+ line="2302"
column="52"/>
</issue>
@@ -1834,7 +1306,7 @@
errorLine2=" ~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetService.java"
- line="2263"
+ line="2331"
column="38"/>
</issue>
@@ -1845,7 +1317,7 @@
errorLine2=" ~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetService.java"
- line="2493"
+ line="2561"
column="56"/>
</issue>
@@ -1856,7 +1328,7 @@
errorLine2=" ~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetService.java"
- line="2562"
+ line="2630"
column="48"/>
</issue>
@@ -1867,40 +1339,18 @@
errorLine2=" ~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetService.java"
- line="2641"
+ line="2709"
column="83"/>
</issue>
<issue
id="VisibleForTests"
message="This method should only be accessed from tests or within private scope"
- errorLine1=" mDatabaseManager.getAudioPolicyMetadata(device);"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java"
- line="208"
- column="34"/>
- </issue>
-
- <issue
- id="VisibleForTests"
- message="This method should only be accessed from tests or within private scope"
- errorLine1=" mDatabaseManager.setAudioPolicyMetadata(device, mHsClientAudioPolicy);"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java"
- line="212"
- column="30"/>
- </issue>
-
- <issue
- id="VisibleForTests"
- message="This method should only be accessed from tests or within private scope"
errorLine1=" mHeadsetService.onConnectionStateChangedFromStateMachine(device, fromState, toState);"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java"
- line="347"
+ line="352"
column="29"/>
</issue>
@@ -1911,7 +1361,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java"
- line="372"
+ line="377"
column="29"/>
</issue>
@@ -1922,7 +1372,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java"
- line="527"
+ line="532"
column="39"/>
</issue>
@@ -1933,7 +1383,7 @@
errorLine2=" ~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java"
- line="588"
+ line="604"
column="43"/>
</issue>
@@ -1944,7 +1394,7 @@
errorLine2=" ~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java"
- line="663"
+ line="684"
column="47"/>
</issue>
@@ -1955,7 +1405,7 @@
errorLine2=" ~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java"
- line="845"
+ line="871"
column="46"/>
</issue>
@@ -1966,7 +1416,7 @@
errorLine2=" ~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java"
- line="849"
+ line="875"
column="46"/>
</issue>
@@ -1977,7 +1427,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java"
- line="1021"
+ line="1047"
column="47"/>
</issue>
@@ -1988,7 +1438,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java"
- line="1037"
+ line="1063"
column="47"/>
</issue>
@@ -1999,7 +1449,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java"
- line="1047"
+ line="1073"
column="43"/>
</issue>
@@ -2010,7 +1460,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java"
- line="1060"
+ line="1086"
column="38"/>
</issue>
@@ -2021,7 +1471,7 @@
errorLine2=" ~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java"
- line="1073"
+ line="1099"
column="42"/>
</issue>
@@ -2032,7 +1482,7 @@
errorLine2=" ~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java"
- line="1081"
+ line="1107"
column="38"/>
</issue>
@@ -2043,7 +1493,7 @@
errorLine2=" ~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java"
- line="1093"
+ line="1119"
column="42"/>
</issue>
@@ -2054,7 +1504,7 @@
errorLine2=" ~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java"
- line="1113"
+ line="1139"
column="46"/>
</issue>
@@ -2065,7 +1515,7 @@
errorLine2=" ~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java"
- line="1147"
+ line="1173"
column="46"/>
</issue>
@@ -2076,7 +1526,7 @@
errorLine2=" ~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java"
- line="1150"
+ line="1176"
column="46"/>
</issue>
@@ -2087,7 +1537,7 @@
errorLine2=" ~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java"
- line="1253"
+ line="1279"
column="34"/>
</issue>
@@ -2098,7 +1548,7 @@
errorLine2=" ~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java"
- line="1274"
+ line="1300"
column="34"/>
</issue>
@@ -2109,7 +1559,7 @@
errorLine2=" ~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java"
- line="1307"
+ line="1342"
column="47"/>
</issue>
@@ -2120,7 +1570,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java"
- line="1334"
+ line="1366"
column="53"/>
</issue>
@@ -2131,7 +1581,7 @@
errorLine2=" ~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java"
- line="1345"
+ line="1377"
column="43"/>
</issue>
@@ -2142,7 +1592,7 @@
errorLine2=" ~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java"
- line="1377"
+ line="1409"
column="47"/>
</issue>
@@ -2153,7 +1603,7 @@
errorLine2=" ~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java"
- line="1393"
+ line="1425"
column="47"/>
</issue>
@@ -2164,7 +1614,7 @@
errorLine2=" ~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java"
- line="1581"
+ line="1618"
column="47"/>
</issue>
@@ -2175,7 +1625,7 @@
errorLine2=" ~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java"
- line="1611"
+ line="1648"
column="46"/>
</issue>
@@ -2186,7 +1636,7 @@
errorLine2=" ~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java"
- line="1923"
+ line="1960"
column="30"/>
</issue>
@@ -2197,7 +1647,7 @@
errorLine2=" ~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java"
- line="1930"
+ line="1967"
column="34"/>
</issue>
@@ -2208,7 +1658,7 @@
errorLine2=" ~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java"
- line="1938"
+ line="1975"
column="34"/>
</issue>
@@ -2219,7 +1669,7 @@
errorLine2=" ~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java"
- line="1945"
+ line="1982"
column="34"/>
</issue>
@@ -2230,7 +1680,7 @@
errorLine2=" ~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java"
- line="1957"
+ line="1994"
column="30"/>
</issue>
@@ -2241,7 +1691,7 @@
errorLine2=" ~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java"
- line="1966"
+ line="2003"
column="34"/>
</issue>
@@ -2252,7 +1702,7 @@
errorLine2=" ~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java"
- line="1970"
+ line="2007"
column="34"/>
</issue>
@@ -2263,7 +1713,7 @@
errorLine2=" ~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java"
- line="1972"
+ line="2009"
column="34"/>
</issue>
@@ -2274,7 +1724,7 @@
errorLine2=" ~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java"
- line="1975"
+ line="2012"
column="30"/>
</issue>
@@ -2285,7 +1735,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java"
- line="2103"
+ line="2140"
column="63"/>
</issue>
@@ -2296,7 +1746,7 @@
errorLine2=" ~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java"
- line="2141"
+ line="2178"
column="26"/>
</issue>
@@ -2307,18 +1757,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java"
- line="2406"
- column="26"/>
- </issue>
-
- <issue
- id="VisibleForTests"
- message="This method should only be accessed from tests or within private scope"
- errorLine1=" mDatabaseManager.setAudioPolicyMetadata(mDevice, policies);"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java"
- line="2467"
+ line="2443"
column="26"/>
</issue>
@@ -2329,7 +1768,7 @@
errorLine2=" ~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java"
- line="2584"
+ line="2621"
column="30"/>
</issue>
@@ -2340,7 +1779,7 @@
errorLine2=" ~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java"
- line="2585"
+ line="2622"
column="30"/>
</issue>
@@ -2351,7 +1790,7 @@
errorLine2=" ~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java"
- line="2593"
+ line="2630"
column="34"/>
</issue>
@@ -2362,7 +1801,7 @@
errorLine2=" ~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java"
- line="2596"
+ line="2633"
column="35"/>
</issue>
@@ -2373,7 +1812,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java"
- line="2723"
+ line="2765"
column="26"/>
</issue>
@@ -2384,7 +1823,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java"
- line="2723"
+ line="2765"
column="49"/>
</issue>
@@ -2395,7 +1834,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hearingaid/HearingAidService.java"
- line="624"
+ line="626"
column="51"/>
</issue>
@@ -2439,7 +1878,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/le_audio/LeAudioService.java"
- line="204"
+ line="207"
column="5"/>
</issue>
@@ -2450,7 +1889,7 @@
errorLine2=" ~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/le_audio/LeAudioService.java"
- line="593"
+ line="607"
column="29"/>
</issue>
@@ -2461,7 +1900,7 @@
errorLine2=" ~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/le_audio/LeAudioService.java"
- line="683"
+ line="695"
column="29"/>
</issue>
@@ -2472,7 +1911,7 @@
errorLine2=" ~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/le_audio/LeAudioService.java"
- line="2775"
+ line="2796"
column="52"/>
</issue>
@@ -2483,7 +1922,7 @@
errorLine2=" ~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/le_audio/LeAudioService.java"
- line="3516"
+ line="3545"
column="52"/>
</issue>
@@ -2494,7 +1933,7 @@
errorLine2=" ~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/le_audio/LeAudioService.java"
- line="4765"
+ line="4759"
column="29"/>
</issue>
@@ -2505,7 +1944,7 @@
errorLine2=" ~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/mapclient/MceStateMachine.java"
- line="287"
+ line="289"
column="22"/>
</issue>
@@ -2516,7 +1955,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/pan/PanNativeInterface.java"
- line="61"
+ line="65"
column="21"/>
</issue>
@@ -2527,7 +1966,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/btservice/PhonePolicy.java"
- line="196"
+ line="198"
column="34"/>
</issue>
@@ -2538,7 +1977,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/btservice/PhonePolicy.java"
- line="201"
+ line="203"
column="33"/>
</issue>
@@ -2549,7 +1988,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/btservice/PhonePolicy.java"
- line="586"
+ line="588"
column="37"/>
</issue>
@@ -2560,7 +1999,7 @@
errorLine2=" ~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/btservice/SilenceDeviceManager.java"
- line="249"
+ line="238"
column="25"/>
</issue>
@@ -2571,7 +2010,7 @@
errorLine2=" ~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/btservice/SilenceDeviceManager.java"
- line="253"
+ line="242"
column="28"/>
</issue>
@@ -2582,7 +2021,7 @@
errorLine2=" ~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/tbs/TbsGeneric.java"
- line="175"
+ line="177"
column="48"/>
</issue>
@@ -2598,24 +2037,13 @@
</issue>
<issue
- id="ExportedContentProvider"
- message="Exported content providers can provide access to potentially sensitive data"
- errorLine1=" &lt;provider android:process=&quot;@string/process&quot; android:name=&quot;com.android.bluetooth.avrcpcontroller.AvrcpCoverArtProvider&quot; android:authorities=&quot;com.android.bluetooth.avrcpcontroller.AvrcpCoverArtProvider&quot; android:enabled=&quot;false&quot; android:grantUriPermissions=&quot;true&quot; android:exported=&quot;true&quot;>"
- errorLine2=" ~~~~~~~~">
- <location
- file="./out/soong/.intermediates/packages/modules/Bluetooth/android/app/BluetoothLib/android_common_apex35/manifest_fixer/AndroidManifest.xml"
- line="98"
- column="10"/>
- </issue>
-
- <issue
id="ExportedReceiver"
message="Exported receiver does not require permission"
errorLine1=" &lt;receiver android:process=&quot;@string/process&quot; android:name=&quot;com.android.bluetooth.opp.BluetoothOppReceiver&quot; android:exported=&quot;true&quot; android:enabled=&quot;false&quot;>"
errorLine2=" ~~~~~~~~">
<location
- file="./out/soong/.intermediates/packages/modules/Bluetooth/android/app/BluetoothLib/android_common_apex35/manifest_fixer/AndroidManifest.xml"
- line="125"
+ file="./out/soong/.intermediates/packages/modules/Bluetooth/android/app/BluetoothLib/android_common_apex36/manifest_fixer/AndroidManifest.xml"
+ line="40"
column="10"/>
</issue>
@@ -2625,8 +2053,8 @@
errorLine1=" &lt;service android:process=&quot;@string/process&quot; android:name=&quot;com.android.bluetooth.avrcpcontroller.BluetoothMediaBrowserService&quot; android:enabled=&quot;true&quot; android:exported=&quot;true&quot; android:label=&quot;@string/a2dp_sink_mbs_label&quot;>"
errorLine2=" ~~~~~~~">
<location
- file="./out/soong/.intermediates/packages/modules/Bluetooth/android/app/BluetoothLib/android_common_apex35/manifest_fixer/AndroidManifest.xml"
- line="92"
+ file="./out/soong/.intermediates/packages/modules/Bluetooth/android/app/BluetoothLib/android_common_apex36/manifest_fixer/AndroidManifest.xml"
+ line="17"
column="10"/>
</issue>
@@ -2636,63 +2064,41 @@
errorLine1=" &lt;service android:process=&quot;@string/process&quot; android:name=&quot;com.android.bluetooth.pbapclient.PbapClientAccountAuthenticatorService&quot; android:enabled=&quot;false&quot; android:exported=&quot;true&quot;>"
errorLine2=" ~~~~~~~">
<location
- file="./out/soong/.intermediates/packages/modules/Bluetooth/android/app/BluetoothLib/android_common_apex35/manifest_fixer/AndroidManifest.xml"
- line="200"
+ file="./out/soong/.intermediates/packages/modules/Bluetooth/android/app/BluetoothLib/android_common_apex36/manifest_fixer/AndroidManifest.xml"
+ line="113"
column="10"/>
</issue>
<issue
- id="InvalidPermission"
- message="Protecting an unsupported element with a permission is a no-op and potentially dangerous"
- errorLine1=" &lt;path-permission android:pathPrefix=&quot;/btopp&quot; android:permission=&quot;android.permission.ACCESS_BLUETOOTH_SHARE&quot;/>"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="./out/soong/.intermediates/packages/modules/Bluetooth/android/app/BluetoothLib/android_common_apex35/manifest_fixer/AndroidManifest.xml"
- line="123"
- column="58"/>
- </issue>
-
- <issue
id="ExpiredTargetSdkVersion"
message="Google Play requires that apps target API level 33 or higher."
errorLine1=" &lt;uses-sdk android:minSdkVersion=&quot;33&quot; android:targetSdkVersion=&quot;16&quot;/>"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
- file="./out/soong/.intermediates/packages/modules/Bluetooth/android/app/BluetoothLib/android_common_apex35/manifest_fixer/AndroidManifest.xml"
- line="74"
+ file="./out/soong/.intermediates/packages/modules/Bluetooth/android/app/BluetoothLib/android_common_apex36/manifest_fixer/AndroidManifest.xml"
+ line="3"
column="42"/>
</issue>
<issue
- id="QueryAllPackagesPermission"
- message="A `&lt;queries>` declaration should generally be used instead of QUERY_ALL_PACKAGES; see https://g.co/dev/packagevisibility for details"
- errorLine1=" &lt;uses-permission android:name=&quot;android.permission.QUERY_ALL_PACKAGES&quot;/>"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="./out/soong/.intermediates/packages/modules/Bluetooth/android/app/BluetoothLib/android_common_apex35/manifest_fixer/AndroidManifest.xml"
- line="47"
- column="22"/>
- </issue>
-
- <issue
id="Wakelock"
message="The `release()` call is not always reached (can exit the method via path acquire() → d() → removeMessages() → sendMessageDelayed() → obtainMessage() → break → exit; use try/finally to ensure `release` is always called)"
errorLine1=" mWakeLock.release();"
errorLine2=" ~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/map/BluetoothMapService.java"
- line="467"
+ line="470"
column="35"/>
</issue>
<issue
id="Wakelock"
- message="The `release()` call is not always reached (because of a possible exception in the path acquire() → try → sleep() → if → ! → then → connect() → = → loop → if → ! → then → doSend() → exit; use try/finally to ensure `release` is always called)"
+ message="The `release()` call is not always reached (because of a possible exception in the path acquire() → try → sleep() → if → ! → then → connect() → loop → if → ! → then → doSend() → exit; use try/finally to ensure `release` is always called)"
errorLine1=" mWakeLock.release();"
errorLine2=" ~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/opp/BluetoothOppObexClientSession.java"
- line="201"
+ line="196"
column="27"/>
</issue>
@@ -2703,7 +2109,7 @@
errorLine2=" ~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/pbap/BluetoothPbapService.java"
- line="574"
+ line="580"
column="35"/>
</issue>
@@ -2714,7 +2120,7 @@
errorLine2=" ~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/sap/SapService.java"
- line="511"
+ line="515"
column="43"/>
</issue>
@@ -2725,7 +2131,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/btservice/AdapterService.java"
- line="6561"
+ line="6457"
column="17"/>
</issue>
@@ -2736,7 +2142,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/map/BluetoothMapService.java"
- line="273"
+ line="276"
column="13"/>
</issue>
@@ -2747,7 +2153,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/map/BluetoothMapService.java"
- line="456"
+ line="459"
column="25"/>
</issue>
@@ -2758,7 +2164,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/opp/BluetoothOppObexClientSession.java"
- line="162"
+ line="158"
column="13"/>
</issue>
@@ -2769,7 +2175,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/opp/BluetoothOppObexServerSession.java"
- line="310"
+ line="307"
column="13"/>
</issue>
@@ -2780,7 +2186,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/pbap/BluetoothPbapService.java"
- line="558"
+ line="564"
column="25"/>
</issue>
@@ -2791,7 +2197,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/sap/SapService.java"
- line="302"
+ line="306"
column="13"/>
</issue>
@@ -2802,7 +2208,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/sap/SapService.java"
- line="500"
+ line="504"
column="33"/>
</issue>
@@ -2813,18 +2219,40 @@
errorLine2="~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/btservice/AdapterSuspend.java"
- line="36"
+ line="37"
column="1"/>
</issue>
<issue
id="ObsoleteSdkInt"
+ message="Unnecessary; SDK_INT is always >= 35"
+ errorLine1=" @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/BluetoothMethodProxy.java"
+ line="304"
+ column="5"/>
+ </issue>
+
+ <issue
+ id="ObsoleteSdkInt"
+ message="Unnecessary; SDK_INT is always >= 35"
+ errorLine1=" @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/opp/BluetoothOppLauncherActivity.java"
+ line="337"
+ column="5"/>
+ </issue>
+
+ <issue
+ id="ObsoleteSdkInt"
message="Unnecessary; SDK_INT is always >= 34"
errorLine1=" @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/btservice/MetricsLogger.java"
- line="628"
+ line="585"
column="5"/>
</issue>
@@ -2835,7 +2263,7 @@
errorLine2=" ^">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/btservice/AdapterService.java"
- line="755"
+ line="746"
column="9"/>
</issue>
@@ -2912,7 +2340,7 @@
errorLine2=" ^">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/opp/BluetoothOppNotification.java"
- line="230"
+ line="228"
column="13"/>
</issue>
@@ -2945,7 +2373,7 @@
errorLine2=" ^">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hid/HidHostService.java"
- line="335"
+ line="331"
column="13"/>
</issue>
@@ -2956,7 +2384,7 @@
errorLine2=" ^">
<location
file="packages/modules/Bluetooth/android/app/src/com/android/bluetooth/sap/SapService.java"
- line="462"
+ line="466"
column="13"/>
</issue>
@@ -3942,17 +3370,6 @@
<issue
id="TypographyEllipsis"
message="Replace &quot;...&quot; with ellipsis character (…, &amp;#8230;) ?"
- errorLine1=" &lt;string name=&quot;enabling_progress_title&quot; msgid=&quot;5262637688863903594&quot;>&quot;Palun oodake ...&quot;&lt;/string>"
- errorLine2=" ~~~~~~~~~~~~~~~~~~">
- <location
- file="packages/modules/Bluetooth/android/app/res/values-et/strings.xml"
- line="77"
- column="72"/>
- </issue>
-
- <issue
- id="TypographyEllipsis"
- message="Replace &quot;...&quot; with ellipsis character (…, &amp;#8230;) ?"
errorLine1=" &lt;string name=&quot;enabling_progress_title&quot; msgid=&quot;5262637688863903594&quot;>&quot;Veuillez patienter...&quot;&lt;/string>"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
<location
diff --git a/android/app/lint-baseline.xml b/android/app/lint-baseline.xml
index 256dbfab50..c50678ee6d 100644
--- a/android/app/lint-baseline.xml
+++ b/android/app/lint-baseline.xml
@@ -2,17 +2,6 @@
<issues format="6" by="lint 8.4.0-alpha08" type="baseline" client="" dependencies="true" name="" variant="all" version="8.4.0-alpha08">
<issue
- id="UnknownIssueId"
- message="Unknown issue id &quot;GetterSetterNullability&quot;"
- errorLine1=" &lt;issue id=&apos;GetterSetterNullability&apos; severity=&apos;error&apos; />"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="./out/lint.xml"
- line="125"
- column="3"/>
- </issue>
-
- <issue
id="ScrollViewSize"
message="This LinearLayout should use `android:layout_height=&quot;wrap_content&quot;`"
errorLine1=" android:layout_height=&quot;match_parent&quot;"
@@ -51,7 +40,7 @@
errorLine1="&lt;manifest xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;"
errorLine2=" ~~~~~~~~">
<location
- file="./out/soong/.intermediates/packages/modules/Bluetooth/android/app/Bluetooth/android_common_apex35/manifest_merger/AndroidManifest.xml"
+ file="./out/soong/.intermediates/packages/modules/Bluetooth/android/app/Bluetooth/android_common_apex36/manifest_merger/AndroidManifest.xml"
line="2"
column="2"/>
</issue>
@@ -62,7 +51,7 @@
errorLine1="&lt;manifest xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;"
errorLine2=" ~~~~~~~~">
<location
- file="./out/soong/.intermediates/packages/modules/Bluetooth/android/app/Bluetooth/android_common_apex35/manifest_merger/AndroidManifest.xml"
+ file="./out/soong/.intermediates/packages/modules/Bluetooth/android/app/Bluetooth/android_common_apex36/manifest_merger/AndroidManifest.xml"
line="2"
column="2"/>
</issue>
@@ -73,7 +62,7 @@
errorLine1=" &lt;provider"
errorLine2=" ~~~~~~~~">
<location
- file="./out/soong/.intermediates/packages/modules/Bluetooth/android/app/Bluetooth/android_common_apex35/manifest_merger/AndroidManifest.xml"
+ file="./out/soong/.intermediates/packages/modules/Bluetooth/android/app/Bluetooth/android_common_apex36/manifest_merger/AndroidManifest.xml"
line="144"
column="10"/>
</issue>
@@ -84,7 +73,7 @@
errorLine1=" &lt;receiver"
errorLine2=" ~~~~~~~~">
<location
- file="./out/soong/.intermediates/packages/modules/Bluetooth/android/app/Bluetooth/android_common_apex35/manifest_merger/AndroidManifest.xml"
+ file="./out/soong/.intermediates/packages/modules/Bluetooth/android/app/Bluetooth/android_common_apex36/manifest_merger/AndroidManifest.xml"
line="209"
column="10"/>
</issue>
@@ -95,7 +84,7 @@
errorLine1=" &lt;service"
errorLine2=" ~~~~~~~">
<location
- file="./out/soong/.intermediates/packages/modules/Bluetooth/android/app/Bluetooth/android_common_apex35/manifest_merger/AndroidManifest.xml"
+ file="./out/soong/.intermediates/packages/modules/Bluetooth/android/app/Bluetooth/android_common_apex36/manifest_merger/AndroidManifest.xml"
line="129"
column="10"/>
</issue>
@@ -106,7 +95,7 @@
errorLine1=" &lt;service"
errorLine2=" ~~~~~~~">
<location
- file="./out/soong/.intermediates/packages/modules/Bluetooth/android/app/Bluetooth/android_common_apex35/manifest_merger/AndroidManifest.xml"
+ file="./out/soong/.intermediates/packages/modules/Bluetooth/android/app/Bluetooth/android_common_apex36/manifest_merger/AndroidManifest.xml"
line="348"
column="10"/>
</issue>
@@ -117,7 +106,7 @@
errorLine1=" android:permission=&quot;android.permission.ACCESS_BLUETOOTH_SHARE&quot; />"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
- file="./out/soong/.intermediates/packages/modules/Bluetooth/android/app/Bluetooth/android_common_apex35/manifest_merger/AndroidManifest.xml"
+ file="./out/soong/.intermediates/packages/modules/Bluetooth/android/app/Bluetooth/android_common_apex36/manifest_merger/AndroidManifest.xml"
line="206"
column="17"/>
</issue>
@@ -128,7 +117,7 @@
errorLine1=" &lt;uses-permission android:name=&quot;android.permission.QUERY_ALL_PACKAGES&quot; />"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
- file="./out/soong/.intermediates/packages/modules/Bluetooth/android/app/Bluetooth/android_common_apex35/manifest_merger/AndroidManifest.xml"
+ file="./out/soong/.intermediates/packages/modules/Bluetooth/android/app/Bluetooth/android_common_apex36/manifest_merger/AndroidManifest.xml"
line="61"
column="22"/>
</issue>
@@ -1126,17 +1115,6 @@
<issue
id="TypographyEllipsis"
message="Replace &quot;...&quot; with ellipsis character (…, &amp;#8230;) ?"
- errorLine1=" &lt;string name=&quot;enabling_progress_title&quot; msgid=&quot;5262637688863903594&quot;>&quot;Palun oodake ...&quot;&lt;/string>"
- errorLine2=" ~~~~~~~~~~~~~~~~~~">
- <location
- file="packages/modules/Bluetooth/android/app/res/values-et/strings.xml"
- line="77"
- column="72"/>
- </issue>
-
- <issue
- id="TypographyEllipsis"
- message="Replace &quot;...&quot; with ellipsis character (…, &amp;#8230;) ?"
errorLine1=" &lt;string name=&quot;enabling_progress_title&quot; msgid=&quot;5262637688863903594&quot;>&quot;Veuillez patienter...&quot;&lt;/string>"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
<location
diff --git a/android/app/src/com/android/bluetooth/BluetoothEventLogger.java b/android/app/src/com/android/bluetooth/BluetoothEventLogger.java
index c0db3988fa..db2d7f56ef 100644
--- a/android/app/src/com/android/bluetooth/BluetoothEventLogger.java
+++ b/android/app/src/com/android/bluetooth/BluetoothEventLogger.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/android/app/src/com/android/bluetooth/BluetoothMethodProxy.java b/android/app/src/com/android/bluetooth/BluetoothMethodProxy.java
index 3141b83af0..a4c265adf7 100644
--- a/android/app/src/com/android/bluetooth/BluetoothMethodProxy.java
+++ b/android/app/src/com/android/bluetooth/BluetoothMethodProxy.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -306,4 +306,9 @@ public class BluetoothMethodProxy {
ComponentCaller caller, Uri uri, int modeFlags) {
return caller.checkContentUriPermission(uri, modeFlags);
}
+
+ /** Proxies {@link Context#grantUriPermission(String, Uri, int)}. } */
+ public void grantUriPermission(Context context, String packageName, Uri uri, int modeFlags) {
+ context.grantUriPermission(packageName, uri, modeFlags);
+ }
}
diff --git a/android/app/src/com/android/bluetooth/Utils.java b/android/app/src/com/android/bluetooth/Utils.java
index 1f8f182b67..3a681bb7e7 100644
--- a/android/app/src/com/android/bluetooth/Utils.java
+++ b/android/app/src/com/android/bluetooth/Utils.java
@@ -100,6 +100,14 @@ public final class Utils {
public static final String TAG_PREFIX_BLUETOOTH = "Bluetooth";
private static final String TAG = TAG_PREFIX_BLUETOOTH + Utils.class.getSimpleName();
+ public static final int BD_ADDR_LEN = 6; // bytes
+ private static final int BD_UUID_LEN = 16; // bytes
+
+ /** Thread pool to handle background and outgoing blocking task */
+ public static final ExecutorService BackgroundExecutor = Executors.newSingleThreadExecutor();
+
+ public static final String PAIRING_UI_PROPERTY = "bluetooth.pairing_ui_package.name";
+
private static final int MICROS_PER_UNIT = 625;
private static final String PTS_TEST_MODE_PROPERTY = "persist.bluetooth.pts";
@@ -115,13 +123,22 @@ public final class Utils {
private static final String KEY_TEMP_ALLOW_LIST_DURATION_MS = "temp_allow_list_duration_ms";
private static final long DEFAULT_TEMP_ALLOW_LIST_DURATION_MS = 20_000;
- static final int BD_ADDR_LEN = 6; // bytes
- static final int BD_UUID_LEN = 16; // bytes
+ private static int sSystemUiUid = USER_HANDLE_NULL.getIdentifier();
+ private static int sForegroundUserId = USER_HANDLE_NULL.getIdentifier();
- /** Thread pool to handle background and outgoing blocking task */
- public static final ExecutorService BackgroundExecutor = Executors.newSingleThreadExecutor();
+ private Utils() {}
- public static final String PAIRING_UI_PROPERTY = "bluetooth.pairing_ui_package.name";
+ public static void setSystemUiUid(int uid) {
+ sSystemUiUid = uid;
+ }
+
+ public static int getForegroundUserId() {
+ return sForegroundUserId;
+ }
+
+ public static void setForegroundUserId(int userId) {
+ sForegroundUserId = userId;
+ }
/**
* Check if dual mode audio is enabled. This is set via the system property
@@ -347,17 +364,6 @@ public final class Utils {
return converter.getLong(offset);
}
- public static String byteArrayToString(byte[] valueBuf) {
- StringBuilder sb = new StringBuilder();
- for (int idx = 0; idx < valueBuf.length; idx++) {
- if (idx != 0) {
- sb.append(" ");
- }
- sb.append(formatSimple("%02x", valueBuf[idx]));
- }
- return sb.toString();
- }
-
/**
* A parser to transfer a byte array to a UTF8 string
*
@@ -429,22 +435,6 @@ public final class Utils {
return puuids;
}
- static int sSystemUiUid = USER_HANDLE_NULL.getIdentifier();
-
- public static void setSystemUiUid(int uid) {
- Utils.sSystemUiUid = uid;
- }
-
- static int sForegroundUserId = USER_HANDLE_NULL.getIdentifier();
-
- public static int getForegroundUserId() {
- return Utils.sForegroundUserId;
- }
-
- public static void setForegroundUserId(int userId) {
- Utils.sForegroundUserId = userId;
- }
-
/**
* Enforces that a Companion Device Manager (CDM) association exists between the calling
* application and the Bluetooth Device.
@@ -634,6 +624,13 @@ public final class Utils {
return checkPermissionForDataDelivery(context, BLUETOOTH_CONNECT, source, message);
}
+ @SuppressLint("AndroidFrameworkRequiresPermission") // This method enforce the permission
+ @RequiresPermission(BLUETOOTH_CONNECT)
+ public static boolean checkConnectPermissionForDataDelivery(
+ Context context, AttributionSource source, String tag, String method) {
+ return checkConnectPermissionForDataDelivery(context, source, tag + "." + method + "()");
+ }
+
/**
* Returns true if the BLUETOOTH_SCAN permission is granted for the calling app. Returns false
* if the result is a soft denial. Throws SecurityException if the result is a hard denial.
@@ -656,8 +653,9 @@ public final class Utils {
@SuppressLint("AndroidFrameworkRequiresPermission") // This method enforce the permission
@RequiresPermission(BLUETOOTH_SCAN)
public static boolean checkScanPermissionForDataDelivery(
- Context context, AttributionSource source, String message) {
- return checkPermissionForDataDelivery(context, BLUETOOTH_SCAN, source, message);
+ Context context, AttributionSource source, String tag, String method) {
+ return checkPermissionForDataDelivery(
+ context, BLUETOOTH_SCAN, source, tag + "." + method + "()");
}
/**
@@ -750,7 +748,7 @@ public final class Utils {
|| (UserHandle.getAppId(Process.SYSTEM_UID) == UserHandle.getAppId(callingUid));
}
- public static boolean checkCallerIsSystemOrActiveUser(String tag) {
+ static boolean checkCallerIsSystemOrActiveUser(String tag) {
final boolean res = checkCallerIsSystemOrActiveUser();
if (!res) {
Log.w(TAG, tag + " - Not allowed for non-active user and non-system user");
@@ -758,10 +756,6 @@ public final class Utils {
return res;
}
- public static boolean callerIsSystemOrActiveUser(String tag, String method) {
- return checkCallerIsSystemOrActiveUser(tag + "." + method + "()");
- }
-
/**
* Checks if the caller to the method is system server.
*
@@ -1189,13 +1183,15 @@ public final class Utils {
return "NO SUBSCRIPTION";
}
- if (BigInteger.valueOf(cccValue).testBit(0) && BigInteger.valueOf(cccValue).testBit(1)) {
+ final boolean isBit0Set = BigInteger.valueOf(cccValue).testBit(0);
+ final boolean isBit1Set = BigInteger.valueOf(cccValue).testBit(1);
+ if (isBit0Set && isBit1Set) {
return "NOTIFICATION|INDICATION";
}
- if (BigInteger.valueOf(cccValue).testBit(0)) {
+ if (isBit0Set) {
return "NOTIFICATION";
}
- if (BigInteger.valueOf(cccValue).testBit(1)) {
+ if (isBit1Set) {
return "INDICATION";
}
return "";
diff --git a/android/app/src/com/android/bluetooth/a2dp/A2dpCodecConfig.java b/android/app/src/com/android/bluetooth/a2dp/A2dpCodecConfig.java
index 340827bd09..30733e2a7f 100644
--- a/android/app/src/com/android/bluetooth/a2dp/A2dpCodecConfig.java
+++ b/android/app/src/com/android/bluetooth/a2dp/A2dpCodecConfig.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 The Android Open Source Project
+ * Copyright (C) 2018 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.
diff --git a/android/app/src/com/android/bluetooth/a2dp/A2dpNativeCallback.java b/android/app/src/com/android/bluetooth/a2dp/A2dpNativeCallback.java
index 314811f71c..5fd94dfea0 100644
--- a/android/app/src/com/android/bluetooth/a2dp/A2dpNativeCallback.java
+++ b/android/app/src/com/android/bluetooth/a2dp/A2dpNativeCallback.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 The Android Open Source Project
+ * Copyright (C) 2024 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.
diff --git a/android/app/src/com/android/bluetooth/a2dp/A2dpNativeInterface.java b/android/app/src/com/android/bluetooth/a2dp/A2dpNativeInterface.java
index 67beb274d5..fe74b2facd 100644
--- a/android/app/src/com/android/bluetooth/a2dp/A2dpNativeInterface.java
+++ b/android/app/src/com/android/bluetooth/a2dp/A2dpNativeInterface.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017 The Android Open Source Project
+ * Copyright (C) 2017 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.
diff --git a/android/app/src/com/android/bluetooth/a2dp/A2dpService.java b/android/app/src/com/android/bluetooth/a2dp/A2dpService.java
index e739c24c99..de37a5b3f4 100644
--- a/android/app/src/com/android/bluetooth/a2dp/A2dpService.java
+++ b/android/app/src/com/android/bluetooth/a2dp/A2dpService.java
@@ -26,8 +26,6 @@ import static android.bluetooth.BluetoothProfile.STATE_CONNECTING;
import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTED;
import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTING;
-import static com.android.bluetooth.Utils.checkCallerTargetSdk;
-
import static java.util.Objects.requireNonNull;
import static java.util.Objects.requireNonNullElseGet;
@@ -44,27 +42,22 @@ import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothUuid;
import android.bluetooth.BufferConstraints;
-import android.bluetooth.IBluetoothA2dp;
import android.companion.CompanionDeviceManager;
-import android.content.AttributionSource;
import android.content.Intent;
import android.media.AudioDeviceCallback;
import android.media.AudioDeviceInfo;
import android.media.AudioManager;
import android.media.BluetoothProfileConnectionInfo;
-import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.sysprop.BluetoothProperties;
import android.util.Log;
-import com.android.bluetooth.BluetoothMetricsProto;
import com.android.bluetooth.BluetoothStatsLog;
import com.android.bluetooth.Utils;
import com.android.bluetooth.btservice.ActiveDeviceManager;
import com.android.bluetooth.btservice.AdapterService;
-import com.android.bluetooth.btservice.MetricsLogger;
import com.android.bluetooth.btservice.ProfileService;
import com.android.bluetooth.btservice.ServiceFactory;
import com.android.bluetooth.btservice.storage.DatabaseManager;
@@ -74,7 +67,6 @@ import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
@@ -169,7 +161,7 @@ public class A2dpService extends ProfileService {
@Override
protected IProfileServiceBinder initBinder() {
- return new BluetoothA2dpBinder(this);
+ return new A2dpServiceBinder(this);
}
@Override
@@ -204,6 +196,10 @@ public class A2dpService extends ProfileService {
mHandler.removeCallbacksAndMessages(null);
}
+ CompanionDeviceManager getCompanionDeviceManager() {
+ return mCompanionDeviceManager;
+ }
+
public static synchronized A2dpService getA2dpService() {
if (sA2dpService == null) {
Log.w(TAG, "getA2dpService(): service is null");
@@ -1002,13 +998,7 @@ public class A2dpService extends ProfileService {
return null;
}
Log.d(TAG, "Creating a new state machine for " + device);
- sm =
- new A2dpStateMachine(
- this,
- device,
- mNativeInterface,
- mA2dpOffloadEnabled,
- mLooper);
+ sm = new A2dpStateMachine(this, device, mNativeInterface, mA2dpOffloadEnabled, mLooper);
mStateMachines.put(device, sm);
return sm;
}
@@ -1306,9 +1296,6 @@ public class A2dpService extends ProfileService {
if ((device == null) || (fromState == toState)) {
return;
}
- if (toState == STATE_CONNECTED) {
- MetricsLogger.logProfileConnectionEvent(BluetoothMetricsProto.ProfileId.A2DP);
- }
// Set the active device if only one connected device is supported and it was connected
if (toState == STATE_CONNECTED && (mMaxConnectedAudioDevices == 1)) {
setActiveDevice(device);
@@ -1349,320 +1336,6 @@ public class A2dpService extends ProfileService {
: null;
}
- /** Binder object: must be a static class or memory leak may occur. */
- @VisibleForTesting
- static class BluetoothA2dpBinder extends IBluetoothA2dp.Stub implements IProfileServiceBinder {
- private A2dpService mService;
-
- @RequiresPermission(BLUETOOTH_CONNECT)
- private A2dpService getServiceAndEnforceConnect(AttributionSource source) {
- // Cache mService because it can change while getService is called
- A2dpService service = mService;
-
- if (Utils.isInstrumentationTestMode()) {
- return service;
- }
-
- if (!Utils.checkServiceAvailable(service, TAG)
- || !Utils.checkCallerIsSystemOrActiveOrManagedUser(service, TAG)
- || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
- return null;
- }
- return service;
- }
-
- private A2dpService getService() {
- // Cache mService because it can change while getService is called
- A2dpService service = mService;
-
- if (Utils.isInstrumentationTestMode()) {
- return service;
- }
-
- if (!Utils.checkServiceAvailable(service, TAG)
- || !Utils.checkCallerIsSystemOrActiveOrManagedUser(service, TAG)) {
- return null;
- }
- return service;
- }
-
- BluetoothA2dpBinder(A2dpService svc) {
- mService = svc;
- }
-
- @Override
- public void cleanup() {
- mService = null;
- }
-
- @Override
- public boolean connect(BluetoothDevice device, AttributionSource source) {
- A2dpService service = getServiceAndEnforceConnect(source);
- if (service == null) {
- return false;
- }
-
- return service.connect(device);
- }
-
- @Override
- public boolean disconnect(BluetoothDevice device, AttributionSource source) {
- A2dpService service = getServiceAndEnforceConnect(source);
- if (service == null) {
- return false;
- }
-
- return service.disconnect(device);
- }
-
- @Override
- public List<BluetoothDevice> getConnectedDevices(AttributionSource source) {
- A2dpService service = getServiceAndEnforceConnect(source);
- if (service == null) {
- return Collections.emptyList();
- }
-
- return service.getConnectedDevices();
- }
-
- @Override
- public List<BluetoothDevice> getDevicesMatchingConnectionStates(
- int[] states, AttributionSource source) {
- A2dpService service = getServiceAndEnforceConnect(source);
- if (service == null) {
- return Collections.emptyList();
- }
-
- return service.getDevicesMatchingConnectionStates(states);
- }
-
- @Override
- public int getConnectionState(BluetoothDevice device, AttributionSource source) {
- A2dpService service = getServiceAndEnforceConnect(source);
- if (service == null) {
- return STATE_DISCONNECTED;
- }
-
- return service.getConnectionState(device);
- }
-
- @Override
- public boolean setActiveDevice(BluetoothDevice device, AttributionSource source) {
- A2dpService service = getServiceAndEnforceConnect(source);
- if (service == null) {
- return false;
- }
-
- if (device == null) {
- return service.removeActiveDevice(false);
- } else {
- return service.setActiveDevice(device);
- }
- }
-
- @Override
- public BluetoothDevice getActiveDevice(AttributionSource source) {
- A2dpService service = getServiceAndEnforceConnect(source);
- if (service == null) {
- return null;
- }
-
- return service.getActiveDevice();
- }
-
- @Override
- public boolean setConnectionPolicy(
- BluetoothDevice device, int connectionPolicy, AttributionSource source) {
- A2dpService service = getServiceAndEnforceConnect(source);
- if (service == null) {
- return false;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- return service.setConnectionPolicy(device, connectionPolicy);
- }
-
- @Override
- public int getConnectionPolicy(BluetoothDevice device, AttributionSource source) {
- A2dpService service = getServiceAndEnforceConnect(source);
- if (service == null) {
- return CONNECTION_POLICY_UNKNOWN;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- return service.getConnectionPolicy(device);
- }
-
- @Override
- public void setAvrcpAbsoluteVolume(int volume, AttributionSource source) {
- A2dpService service = getServiceAndEnforceConnect(source);
- if (service == null) {
- return;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- service.setAvrcpAbsoluteVolume(volume);
- }
-
- @Override
- public boolean isA2dpPlaying(BluetoothDevice device, AttributionSource source) {
- A2dpService service = getServiceAndEnforceConnect(source);
- if (service == null) {
- return false;
- }
-
- return service.isA2dpPlaying(device);
- }
-
- @Override
- public List<BluetoothCodecType> getSupportedCodecTypes() {
- A2dpService service = getService();
- if (service == null) {
- return Collections.emptyList();
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- return service.getSupportedCodecTypes();
- }
-
- @Override
- public BluetoothCodecStatus getCodecStatus(
- BluetoothDevice device, AttributionSource source) {
- requireNonNull(device);
- A2dpService service = getServiceAndEnforceConnect(source);
- if (service == null) {
- return null;
- }
-
- Utils.enforceCdmAssociationIfNotBluetoothPrivileged(
- service, service.mCompanionDeviceManager, source, device);
-
- return service.getCodecStatus(device);
- }
-
- @Override
- public void setCodecConfigPreference(
- BluetoothDevice device,
- BluetoothCodecConfig codecConfig,
- AttributionSource source) {
- requireNonNull(device);
- A2dpService service = getServiceAndEnforceConnect(source);
- if (service == null) {
- return;
- }
-
- Utils.enforceCdmAssociationIfNotBluetoothPrivileged(
- service, service.mCompanionDeviceManager, source, device);
-
- service.setCodecConfigPreference(device, codecConfig);
- }
-
- @Override
- public void enableOptionalCodecs(BluetoothDevice device, AttributionSource source) {
- A2dpService service = getServiceAndEnforceConnect(source);
- if (service == null) {
- return;
- }
-
- if (checkCallerTargetSdk(
- mService, source.getPackageName(), Build.VERSION_CODES.TIRAMISU)) {
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- }
- service.enableOptionalCodecs(device);
- }
-
- @Override
- public void disableOptionalCodecs(BluetoothDevice device, AttributionSource source) {
- A2dpService service = getServiceAndEnforceConnect(source);
- if (service == null) {
- return;
- }
-
- if (checkCallerTargetSdk(
- mService, source.getPackageName(), Build.VERSION_CODES.TIRAMISU)) {
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- }
- service.disableOptionalCodecs(device);
- }
-
- @Override
- public int isOptionalCodecsSupported(BluetoothDevice device, AttributionSource source) {
- A2dpService service = getServiceAndEnforceConnect(source);
- if (service == null) {
- return BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN;
- }
-
- if (checkCallerTargetSdk(
- mService, source.getPackageName(), Build.VERSION_CODES.TIRAMISU)) {
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- }
- return service.getSupportsOptionalCodecs(device);
- }
-
- @Override
- public int isOptionalCodecsEnabled(BluetoothDevice device, AttributionSource source) {
- A2dpService service = getServiceAndEnforceConnect(source);
- if (service == null) {
- return BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN;
- }
-
- if (checkCallerTargetSdk(
- mService, source.getPackageName(), Build.VERSION_CODES.TIRAMISU)) {
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- }
- return service.getOptionalCodecsEnabled(device);
- }
-
- @Override
- public void setOptionalCodecsEnabled(
- BluetoothDevice device, int value, AttributionSource source) {
- A2dpService service = getServiceAndEnforceConnect(source);
- if (service == null) {
- return;
- }
-
- if (checkCallerTargetSdk(
- mService, source.getPackageName(), Build.VERSION_CODES.TIRAMISU)) {
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- }
- service.setOptionalCodecsEnabled(device, value);
- }
-
- @Override
- public int getDynamicBufferSupport(AttributionSource source) {
- A2dpService service = getServiceAndEnforceConnect(source);
- if (service == null) {
- return BluetoothA2dp.DYNAMIC_BUFFER_SUPPORT_NONE;
- }
-
- return service.getDynamicBufferSupport();
- }
-
- @Override
- public BufferConstraints getBufferConstraints(AttributionSource source) {
- A2dpService service = getServiceAndEnforceConnect(source);
- if (service == null) {
- return null;
- }
-
- return service.getBufferConstraints();
- }
-
- @Override
- public boolean setBufferLengthMillis(int codec, int value, AttributionSource source) {
- A2dpService service = getServiceAndEnforceConnect(source);
- if (service == null) {
- return false;
- }
-
- return service.setBufferLengthMillis(codec, value);
- }
- }
-
@Override
public void dump(StringBuilder sb) {
super.dump(sb);
diff --git a/android/app/src/com/android/bluetooth/a2dp/A2dpServiceBinder.java b/android/app/src/com/android/bluetooth/a2dp/A2dpServiceBinder.java
new file mode 100644
index 0000000000..da8aaae42a
--- /dev/null
+++ b/android/app/src/com/android/bluetooth/a2dp/A2dpServiceBinder.java
@@ -0,0 +1,336 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.bluetooth.a2dp;
+
+import static android.Manifest.permission.BLUETOOTH_CONNECT;
+import static android.Manifest.permission.BLUETOOTH_PRIVILEGED;
+import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_UNKNOWN;
+import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTED;
+
+import static com.android.bluetooth.Utils.checkCallerTargetSdk;
+
+import static java.util.Objects.requireNonNull;
+
+import android.annotation.RequiresPermission;
+import android.bluetooth.BluetoothA2dp;
+import android.bluetooth.BluetoothCodecConfig;
+import android.bluetooth.BluetoothCodecStatus;
+import android.bluetooth.BluetoothCodecType;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BufferConstraints;
+import android.bluetooth.IBluetoothA2dp;
+import android.content.AttributionSource;
+import android.os.Build;
+
+import com.android.bluetooth.Utils;
+import com.android.bluetooth.btservice.ProfileService.IProfileServiceBinder;
+
+import java.util.Collections;
+import java.util.List;
+
+class A2dpServiceBinder extends IBluetoothA2dp.Stub implements IProfileServiceBinder {
+ private static final String TAG = A2dpServiceBinder.class.getSimpleName();
+
+ private A2dpService mService;
+
+ A2dpServiceBinder(A2dpService svc) {
+ mService = svc;
+ }
+
+ @Override
+ public void cleanup() {
+ mService = null;
+ }
+
+ private A2dpService getService() {
+ A2dpService service = mService;
+
+ if (Utils.isInstrumentationTestMode()) {
+ return service;
+ }
+
+ if (!Utils.checkServiceAvailable(service, TAG)
+ || !Utils.checkCallerIsSystemOrActiveOrManagedUser(service, TAG)) {
+ return null;
+ }
+ return service;
+ }
+
+ @RequiresPermission(BLUETOOTH_CONNECT)
+ private A2dpService getServiceAndEnforceConnect(AttributionSource source) {
+ A2dpService service = mService;
+
+ if (Utils.isInstrumentationTestMode()) {
+ return service;
+ }
+
+ if (!Utils.checkServiceAvailable(service, TAG)
+ || !Utils.checkCallerIsSystemOrActiveOrManagedUser(service, TAG)
+ || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
+ return null;
+ }
+ return service;
+ }
+
+ @Override
+ public boolean connect(BluetoothDevice device, AttributionSource source) {
+ A2dpService service = getServiceAndEnforceConnect(source);
+ if (service == null) {
+ return false;
+ }
+ return service.connect(device);
+ }
+
+ @Override
+ public boolean disconnect(BluetoothDevice device, AttributionSource source) {
+ A2dpService service = getServiceAndEnforceConnect(source);
+ if (service == null) {
+ return false;
+ }
+ return service.disconnect(device);
+ }
+
+ @Override
+ public List<BluetoothDevice> getConnectedDevices(AttributionSource source) {
+ A2dpService service = getServiceAndEnforceConnect(source);
+ if (service == null) {
+ return Collections.emptyList();
+ }
+ return service.getConnectedDevices();
+ }
+
+ @Override
+ public List<BluetoothDevice> getDevicesMatchingConnectionStates(
+ int[] states, AttributionSource source) {
+ A2dpService service = getServiceAndEnforceConnect(source);
+ if (service == null) {
+ return Collections.emptyList();
+ }
+ return service.getDevicesMatchingConnectionStates(states);
+ }
+
+ @Override
+ public int getConnectionState(BluetoothDevice device, AttributionSource source) {
+ A2dpService service = getServiceAndEnforceConnect(source);
+ if (service == null) {
+ return STATE_DISCONNECTED;
+ }
+ return service.getConnectionState(device);
+ }
+
+ @Override
+ public boolean setActiveDevice(BluetoothDevice device, AttributionSource source) {
+ A2dpService service = getServiceAndEnforceConnect(source);
+ if (service == null) {
+ return false;
+ }
+
+ if (device == null) {
+ return service.removeActiveDevice(false);
+ } else {
+ return service.setActiveDevice(device);
+ }
+ }
+
+ @Override
+ public BluetoothDevice getActiveDevice(AttributionSource source) {
+ A2dpService service = getServiceAndEnforceConnect(source);
+ if (service == null) {
+ return null;
+ }
+ return service.getActiveDevice();
+ }
+
+ @Override
+ public boolean setConnectionPolicy(
+ BluetoothDevice device, int connectionPolicy, AttributionSource source) {
+ A2dpService service = getServiceAndEnforceConnect(source);
+ if (service == null) {
+ return false;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.setConnectionPolicy(device, connectionPolicy);
+ }
+
+ @Override
+ public int getConnectionPolicy(BluetoothDevice device, AttributionSource source) {
+ A2dpService service = getServiceAndEnforceConnect(source);
+ if (service == null) {
+ return CONNECTION_POLICY_UNKNOWN;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.getConnectionPolicy(device);
+ }
+
+ @Override
+ public void setAvrcpAbsoluteVolume(int volume, AttributionSource source) {
+ A2dpService service = getServiceAndEnforceConnect(source);
+ if (service == null) {
+ return;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ service.setAvrcpAbsoluteVolume(volume);
+ }
+
+ @Override
+ public boolean isA2dpPlaying(BluetoothDevice device, AttributionSource source) {
+ A2dpService service = getServiceAndEnforceConnect(source);
+ if (service == null) {
+ return false;
+ }
+ return service.isA2dpPlaying(device);
+ }
+
+ @Override
+ public List<BluetoothCodecType> getSupportedCodecTypes() {
+ A2dpService service = getService();
+ if (service == null) {
+ return Collections.emptyList();
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.getSupportedCodecTypes();
+ }
+
+ @Override
+ public BluetoothCodecStatus getCodecStatus(BluetoothDevice device, AttributionSource source) {
+ requireNonNull(device);
+ A2dpService service = getServiceAndEnforceConnect(source);
+ if (service == null) {
+ return null;
+ }
+
+ Utils.enforceCdmAssociationIfNotBluetoothPrivileged(
+ service, service.getCompanionDeviceManager(), source, device);
+
+ return service.getCodecStatus(device);
+ }
+
+ @Override
+ public void setCodecConfigPreference(
+ BluetoothDevice device, BluetoothCodecConfig codecConfig, AttributionSource source) {
+ requireNonNull(device);
+ A2dpService service = getServiceAndEnforceConnect(source);
+ if (service == null) {
+ return;
+ }
+
+ Utils.enforceCdmAssociationIfNotBluetoothPrivileged(
+ service, service.getCompanionDeviceManager(), source, device);
+
+ service.setCodecConfigPreference(device, codecConfig);
+ }
+
+ @Override
+ public void enableOptionalCodecs(BluetoothDevice device, AttributionSource source) {
+ A2dpService service = getServiceAndEnforceConnect(source);
+ if (service == null) {
+ return;
+ }
+
+ if (checkCallerTargetSdk(mService, source.getPackageName(), Build.VERSION_CODES.TIRAMISU)) {
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ }
+ service.enableOptionalCodecs(device);
+ }
+
+ @Override
+ public void disableOptionalCodecs(BluetoothDevice device, AttributionSource source) {
+ A2dpService service = getServiceAndEnforceConnect(source);
+ if (service == null) {
+ return;
+ }
+
+ if (checkCallerTargetSdk(mService, source.getPackageName(), Build.VERSION_CODES.TIRAMISU)) {
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ }
+ service.disableOptionalCodecs(device);
+ }
+
+ @Override
+ public int isOptionalCodecsSupported(BluetoothDevice device, AttributionSource source) {
+ A2dpService service = getServiceAndEnforceConnect(source);
+ if (service == null) {
+ return BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN;
+ }
+
+ if (checkCallerTargetSdk(mService, source.getPackageName(), Build.VERSION_CODES.TIRAMISU)) {
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ }
+ return service.getSupportsOptionalCodecs(device);
+ }
+
+ @Override
+ public int isOptionalCodecsEnabled(BluetoothDevice device, AttributionSource source) {
+ A2dpService service = getServiceAndEnforceConnect(source);
+ if (service == null) {
+ return BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN;
+ }
+
+ if (checkCallerTargetSdk(mService, source.getPackageName(), Build.VERSION_CODES.TIRAMISU)) {
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ }
+ return service.getOptionalCodecsEnabled(device);
+ }
+
+ @Override
+ public void setOptionalCodecsEnabled(
+ BluetoothDevice device, int value, AttributionSource source) {
+ A2dpService service = getServiceAndEnforceConnect(source);
+ if (service == null) {
+ return;
+ }
+
+ if (checkCallerTargetSdk(mService, source.getPackageName(), Build.VERSION_CODES.TIRAMISU)) {
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ }
+ service.setOptionalCodecsEnabled(device, value);
+ }
+
+ @Override
+ public int getDynamicBufferSupport(AttributionSource source) {
+ A2dpService service = getServiceAndEnforceConnect(source);
+ if (service == null) {
+ return BluetoothA2dp.DYNAMIC_BUFFER_SUPPORT_NONE;
+ }
+
+ return service.getDynamicBufferSupport();
+ }
+
+ @Override
+ public BufferConstraints getBufferConstraints(AttributionSource source) {
+ A2dpService service = getServiceAndEnforceConnect(source);
+ if (service == null) {
+ return null;
+ }
+
+ return service.getBufferConstraints();
+ }
+
+ @Override
+ public boolean setBufferLengthMillis(int codec, int value, AttributionSource source) {
+ A2dpService service = getServiceAndEnforceConnect(source);
+ if (service == null) {
+ return false;
+ }
+
+ return service.setBufferLengthMillis(codec, value);
+ }
+}
diff --git a/android/app/src/com/android/bluetooth/a2dp/A2dpStackEvent.java b/android/app/src/com/android/bluetooth/a2dp/A2dpStackEvent.java
index 6c66f0119b..314beefbaa 100644
--- a/android/app/src/com/android/bluetooth/a2dp/A2dpStackEvent.java
+++ b/android/app/src/com/android/bluetooth/a2dp/A2dpStackEvent.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017 The Android Open Source Project
+ * Copyright (C) 2017 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.
diff --git a/android/app/src/com/android/bluetooth/a2dp/A2dpStateMachine.java b/android/app/src/com/android/bluetooth/a2dp/A2dpStateMachine.java
index a2e4d0b4d2..697529e63c 100644
--- a/android/app/src/com/android/bluetooth/a2dp/A2dpStateMachine.java
+++ b/android/app/src/com/android/bluetooth/a2dp/A2dpStateMachine.java
@@ -80,7 +80,7 @@ final class A2dpStateMachine extends StateMachine {
static final int MESSAGE_CONNECT = 1;
static final int MESSAGE_DISCONNECT = 2;
- @VisibleForTesting static final int MESSAGE_STACK_EVENT = 101;
+ static final int MESSAGE_STACK_EVENT = 101;
private static final int MESSAGE_CONNECT_TIMEOUT = 201;
@VisibleForTesting static final Duration CONNECT_TIMEOUT = Duration.ofSeconds(30);
@@ -132,9 +132,7 @@ final class A2dpStateMachine extends StateMachine {
public void doQuit() {
log("doQuit for device " + mDevice);
- if (Flags.a2dpBroadcastConnectionStateWhenTurnedOff()
- && mConnectionState != STATE_DISCONNECTED
- && mLastConnectionState != -1) {
+ if (mConnectionState != STATE_DISCONNECTED && mLastConnectionState != -1) {
// Broadcast CONNECTION_STATE_CHANGED when A2dpService is turned off while
// the device is connected
broadcastConnectionState(STATE_DISCONNECTED, mConnectionState);
diff --git a/android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkService.java b/android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkService.java
index 10b9249bad..6750a9a9c8 100644
--- a/android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkService.java
+++ b/android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkService.java
@@ -13,30 +13,24 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package com.android.bluetooth.a2dpsink;
-import static android.Manifest.permission.BLUETOOTH_CONNECT;
-import static android.Manifest.permission.BLUETOOTH_PRIVILEGED;
import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_ALLOWED;
import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
-import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_UNKNOWN;
import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTED;
import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTING;
import static java.util.Objects.requireNonNull;
-import android.annotation.RequiresPermission;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothAudioConfig;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
-import android.bluetooth.IBluetoothA2dpSink;
-import android.content.AttributionSource;
import android.os.Looper;
import android.sysprop.BluetoothProperties;
import android.util.Log;
-import com.android.bluetooth.Utils;
import com.android.bluetooth.btservice.AdapterService;
import com.android.bluetooth.btservice.ProfileService;
import com.android.bluetooth.btservice.storage.DatabaseManager;
@@ -45,7 +39,6 @@ import com.android.internal.annotations.VisibleForTesting;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@@ -177,136 +170,6 @@ public class A2dpSinkService extends ProfileService {
return new A2dpSinkServiceBinder(this);
}
- // Binder object: Must be static class or memory leak may occur
- @VisibleForTesting
- static class A2dpSinkServiceBinder extends IBluetoothA2dpSink.Stub
- implements IProfileServiceBinder {
- private A2dpSinkService mService;
-
- A2dpSinkServiceBinder(A2dpSinkService svc) {
- mService = svc;
- }
-
- @Override
- public void cleanup() {
- mService = null;
- }
-
- @RequiresPermission(BLUETOOTH_CONNECT)
- private A2dpSinkService getService(AttributionSource source) {
- // Cache mService because it can change while getService is called
- A2dpSinkService service = mService;
-
- if (Utils.isInstrumentationTestMode()) {
- return service;
- }
-
- if (!Utils.checkServiceAvailable(service, TAG)
- || !Utils.checkCallerIsSystemOrActiveOrManagedUser(service, TAG)
- || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
- return null;
- }
-
- return service;
- }
-
- @Override
- public boolean connect(BluetoothDevice device, AttributionSource source) {
- A2dpSinkService service = getService(source);
- if (service == null) {
- return false;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- return service.connect(device);
- }
-
- @Override
- public boolean disconnect(BluetoothDevice device, AttributionSource source) {
- A2dpSinkService service = getService(source);
- if (service == null) {
- return false;
- }
- return service.disconnect(device);
- }
-
- @Override
- public List<BluetoothDevice> getConnectedDevices(AttributionSource source) {
- A2dpSinkService service = getService(source);
- if (service == null) {
- return Collections.emptyList();
- }
- return service.getConnectedDevices();
- }
-
- @Override
- public List<BluetoothDevice> getDevicesMatchingConnectionStates(
- int[] states, AttributionSource source) {
- A2dpSinkService service = getService(source);
- if (service == null) {
- return Collections.emptyList();
- }
- return service.getDevicesMatchingConnectionStates(states);
- }
-
- @Override
- public int getConnectionState(BluetoothDevice device, AttributionSource source) {
- A2dpSinkService service = getService(source);
- if (service == null) {
- return STATE_DISCONNECTED;
- }
- return service.getConnectionState(device);
- }
-
- @Override
- public boolean setConnectionPolicy(
- BluetoothDevice device, int connectionPolicy, AttributionSource source) {
- A2dpSinkService service = getService(source);
- if (service == null) {
- return false;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- return service.setConnectionPolicy(device, connectionPolicy);
- }
-
- @Override
- public int getConnectionPolicy(BluetoothDevice device, AttributionSource source) {
- A2dpSinkService service = getService(source);
- if (service == null) {
- return CONNECTION_POLICY_UNKNOWN;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- return service.getConnectionPolicy(device);
- }
-
- @Override
- public boolean isA2dpPlaying(BluetoothDevice device, AttributionSource source) {
- A2dpSinkService service = getService(source);
- if (service == null) {
- return false;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- return service.isA2dpPlaying(device);
- }
-
- @Override
- public BluetoothAudioConfig getAudioConfig(
- BluetoothDevice device, AttributionSource source) {
- A2dpSinkService service = getService(source);
- if (service == null) {
- return null;
- }
- return service.getAudioConfig(device);
- }
- }
-
/* Generic Profile Code */
/**
diff --git a/android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkServiceBinder.java b/android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkServiceBinder.java
new file mode 100644
index 0000000000..851e48a286
--- /dev/null
+++ b/android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkServiceBinder.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.bluetooth.a2dpsink;
+
+import static android.Manifest.permission.BLUETOOTH_CONNECT;
+import static android.Manifest.permission.BLUETOOTH_PRIVILEGED;
+import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_UNKNOWN;
+import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTED;
+
+import android.annotation.RequiresPermission;
+import android.bluetooth.BluetoothAudioConfig;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.IBluetoothA2dpSink;
+import android.content.AttributionSource;
+
+import com.android.bluetooth.Utils;
+import com.android.bluetooth.btservice.ProfileService.IProfileServiceBinder;
+
+import java.util.Collections;
+import java.util.List;
+
+class A2dpSinkServiceBinder extends IBluetoothA2dpSink.Stub implements IProfileServiceBinder {
+ private static final String TAG = A2dpSinkServiceBinder.class.getSimpleName();
+
+ private A2dpSinkService mService;
+
+ A2dpSinkServiceBinder(A2dpSinkService svc) {
+ mService = svc;
+ }
+
+ @Override
+ public void cleanup() {
+ mService = null;
+ }
+
+ @RequiresPermission(BLUETOOTH_CONNECT)
+ private A2dpSinkService getService(AttributionSource source) {
+ A2dpSinkService service = mService;
+
+ if (Utils.isInstrumentationTestMode()) {
+ return service;
+ }
+
+ if (!Utils.checkServiceAvailable(service, TAG)
+ || !Utils.checkCallerIsSystemOrActiveOrManagedUser(service, TAG)
+ || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
+ return null;
+ }
+
+ return service;
+ }
+
+ @Override
+ public boolean connect(BluetoothDevice device, AttributionSource source) {
+ A2dpSinkService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.connect(device);
+ }
+
+ @Override
+ public boolean disconnect(BluetoothDevice device, AttributionSource source) {
+ A2dpSinkService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+ return service.disconnect(device);
+ }
+
+ @Override
+ public List<BluetoothDevice> getConnectedDevices(AttributionSource source) {
+ A2dpSinkService service = getService(source);
+ if (service == null) {
+ return Collections.emptyList();
+ }
+ return service.getConnectedDevices();
+ }
+
+ @Override
+ public List<BluetoothDevice> getDevicesMatchingConnectionStates(
+ int[] states, AttributionSource source) {
+ A2dpSinkService service = getService(source);
+ if (service == null) {
+ return Collections.emptyList();
+ }
+ return service.getDevicesMatchingConnectionStates(states);
+ }
+
+ @Override
+ public int getConnectionState(BluetoothDevice device, AttributionSource source) {
+ A2dpSinkService service = getService(source);
+ if (service == null) {
+ return STATE_DISCONNECTED;
+ }
+ return service.getConnectionState(device);
+ }
+
+ @Override
+ public boolean setConnectionPolicy(
+ BluetoothDevice device, int connectionPolicy, AttributionSource source) {
+ A2dpSinkService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.setConnectionPolicy(device, connectionPolicy);
+ }
+
+ @Override
+ public int getConnectionPolicy(BluetoothDevice device, AttributionSource source) {
+ A2dpSinkService service = getService(source);
+ if (service == null) {
+ return CONNECTION_POLICY_UNKNOWN;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.getConnectionPolicy(device);
+ }
+
+ @Override
+ public boolean isA2dpPlaying(BluetoothDevice device, AttributionSource source) {
+ A2dpSinkService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.isA2dpPlaying(device);
+ }
+
+ @Override
+ public BluetoothAudioConfig getAudioConfig(BluetoothDevice device, AttributionSource source) {
+ A2dpSinkService service = getService(source);
+ if (service == null) {
+ return null;
+ }
+ return service.getAudioConfig(device);
+ }
+}
diff --git a/android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkStateMachine.java b/android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkStateMachine.java
index 18d956b594..7ec05af50d 100644
--- a/android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkStateMachine.java
+++ b/android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkStateMachine.java
@@ -34,7 +34,6 @@ import android.os.Looper;
import android.os.Message;
import android.util.Log;
-import com.android.bluetooth.BluetoothMetricsProto;
import com.android.bluetooth.Utils;
import com.android.bluetooth.btservice.MetricsLogger;
import com.android.bluetooth.btservice.ProfileService;
@@ -316,9 +315,6 @@ class A2dpSinkStateMachine extends StateMachine {
if (mMostRecentState == currentState) {
return;
}
- if (currentState == STATE_CONNECTED) {
- MetricsLogger.logProfileConnectionEvent(BluetoothMetricsProto.ProfileId.A2DP_SINK);
- }
Log.d(TAG, "[" + mDevice + "] Connection state: " + mMostRecentState + "->" + currentState);
Intent intent = new Intent(BluetoothA2dpSink.ACTION_CONNECTION_STATE_CHANGED);
intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, mMostRecentState);
diff --git a/android/app/src/com/android/bluetooth/audio_util/BrowsablePlayerConnector.java b/android/app/src/com/android/bluetooth/audio_util/BrowsablePlayerConnector.java
index 12908fde53..156a54db8e 100644
--- a/android/app/src/com/android/bluetooth/audio_util/BrowsablePlayerConnector.java
+++ b/android/app/src/com/android/bluetooth/audio_util/BrowsablePlayerConnector.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 The Android Open Source Project
+ * Copyright (C) 2018 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.
diff --git a/android/app/src/com/android/bluetooth/audio_util/BrowsedPlayerWrapper.java b/android/app/src/com/android/bluetooth/audio_util/BrowsedPlayerWrapper.java
index 02598dae03..8b9b73d160 100644
--- a/android/app/src/com/android/bluetooth/audio_util/BrowsedPlayerWrapper.java
+++ b/android/app/src/com/android/bluetooth/audio_util/BrowsedPlayerWrapper.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 The Android Open Source Project
+ * Copyright (C) 2018 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.
diff --git a/android/app/src/com/android/bluetooth/audio_util/GPMWrapper.java b/android/app/src/com/android/bluetooth/audio_util/GPMWrapper.java
index a69a6be6f9..e7c45de50e 100644
--- a/android/app/src/com/android/bluetooth/audio_util/GPMWrapper.java
+++ b/android/app/src/com/android/bluetooth/audio_util/GPMWrapper.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 The Android Open Source Project
+ * Copyright (C) 2018 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.
diff --git a/android/app/src/com/android/bluetooth/audio_util/MediaBrowserWrapper.java b/android/app/src/com/android/bluetooth/audio_util/MediaBrowserWrapper.java
index 253eaa50a9..3c235cce76 100644
--- a/android/app/src/com/android/bluetooth/audio_util/MediaBrowserWrapper.java
+++ b/android/app/src/com/android/bluetooth/audio_util/MediaBrowserWrapper.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 The Android Open Source Project
+ * Copyright (C) 2024 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.
@@ -197,7 +197,7 @@ class MediaBrowserWrapper {
mSubscribedIds.put(
rootId, new ArrayList<>(Arrays.asList(callback)));
mWrappedBrowser.subscribe(
- rootId, new BrowserSubscriptionCallback(mediaId));
+ rootId, new BrowserSubscriptionCallback(rootId));
});
} else {
mSubscribedIds.put(mediaId, new ArrayList<>(Arrays.asList(callback)));
diff --git a/android/app/src/com/android/bluetooth/audio_util/MediaPlayerList.java b/android/app/src/com/android/bluetooth/audio_util/MediaPlayerList.java
index 17908cf61c..1098cda6fa 100644
--- a/android/app/src/com/android/bluetooth/audio_util/MediaPlayerList.java
+++ b/android/app/src/com/android/bluetooth/audio_util/MediaPlayerList.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 The Android Open Source Project
+ * Copyright (C) 2018 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.
diff --git a/android/app/src/com/android/bluetooth/audio_util/MediaPlayerWrapper.java b/android/app/src/com/android/bluetooth/audio_util/MediaPlayerWrapper.java
index cca53936a5..29efeaf0be 100644
--- a/android/app/src/com/android/bluetooth/audio_util/MediaPlayerWrapper.java
+++ b/android/app/src/com/android/bluetooth/audio_util/MediaPlayerWrapper.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 The Android Open Source Project
+ * Copyright (C) 2018 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.
diff --git a/android/app/src/com/android/bluetooth/audio_util/PlayerSettingsManager.java b/android/app/src/com/android/bluetooth/audio_util/PlayerSettingsManager.java
index 43733ec15e..6a0f9bd2d7 100644
--- a/android/app/src/com/android/bluetooth/audio_util/PlayerSettingsManager.java
+++ b/android/app/src/com/android/bluetooth/audio_util/PlayerSettingsManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 The Android Open Source Project
+ * Copyright (C) 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.
diff --git a/android/app/src/com/android/bluetooth/audio_util/helpers/PlayStatus.java b/android/app/src/com/android/bluetooth/audio_util/helpers/PlayStatus.java
index adca4be6a9..eccabe6087 100644
--- a/android/app/src/com/android/bluetooth/audio_util/helpers/PlayStatus.java
+++ b/android/app/src/com/android/bluetooth/audio_util/helpers/PlayStatus.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 The Android Open Source Project
+ * Copyright (C) 2018 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.
diff --git a/android/app/src/com/android/bluetooth/audio_util/helpers/PlayerInfo.java b/android/app/src/com/android/bluetooth/audio_util/helpers/PlayerInfo.java
index ada64292f7..a6f5c4ee2f 100644
--- a/android/app/src/com/android/bluetooth/audio_util/helpers/PlayerInfo.java
+++ b/android/app/src/com/android/bluetooth/audio_util/helpers/PlayerInfo.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 The Android Open Source Project
+ * Copyright (C) 2018 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.
diff --git a/android/app/src/com/android/bluetooth/audio_util/mockable/MediaBrowser.java b/android/app/src/com/android/bluetooth/audio_util/mockable/MediaBrowser.java
index 93ef130d43..31063529fa 100644
--- a/android/app/src/com/android/bluetooth/audio_util/mockable/MediaBrowser.java
+++ b/android/app/src/com/android/bluetooth/audio_util/mockable/MediaBrowser.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 The Android Open Source Project
+ * Copyright (C) 2018 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.
diff --git a/android/app/src/com/android/bluetooth/audio_util/mockable/MediaBrowserFactory.java b/android/app/src/com/android/bluetooth/audio_util/mockable/MediaBrowserFactory.java
index 4570af982a..835c09c79e 100644
--- a/android/app/src/com/android/bluetooth/audio_util/mockable/MediaBrowserFactory.java
+++ b/android/app/src/com/android/bluetooth/audio_util/mockable/MediaBrowserFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 The Android Open Source Project
+ * Copyright (C) 2018 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.
diff --git a/android/app/src/com/android/bluetooth/audio_util/mockable/MediaController.java b/android/app/src/com/android/bluetooth/audio_util/mockable/MediaController.java
index a0081b2190..ceec1065f8 100644
--- a/android/app/src/com/android/bluetooth/audio_util/mockable/MediaController.java
+++ b/android/app/src/com/android/bluetooth/audio_util/mockable/MediaController.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 The Android Open Source Project
+ * Copyright (C) 2018 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.
diff --git a/android/app/src/com/android/bluetooth/audio_util/mockable/MediaControllerFactory.java b/android/app/src/com/android/bluetooth/audio_util/mockable/MediaControllerFactory.java
index ff477ac7b4..81734c5bae 100644
--- a/android/app/src/com/android/bluetooth/audio_util/mockable/MediaControllerFactory.java
+++ b/android/app/src/com/android/bluetooth/audio_util/mockable/MediaControllerFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 The Android Open Source Project
+ * Copyright (C) 2018 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.
diff --git a/android/app/src/com/android/bluetooth/audio_util/mockable/MediaPlayerWrapperFactory.java b/android/app/src/com/android/bluetooth/audio_util/mockable/MediaPlayerWrapperFactory.java
index cb2798bdc3..5a8dfe4ab7 100644
--- a/android/app/src/com/android/bluetooth/audio_util/mockable/MediaPlayerWrapperFactory.java
+++ b/android/app/src/com/android/bluetooth/audio_util/mockable/MediaPlayerWrapperFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/android/app/src/com/android/bluetooth/avrcp/AvrcpBipObexServer.java b/android/app/src/com/android/bluetooth/avrcp/AvrcpBipObexServer.java
index 9df35f9388..fc760cd1ae 100644
--- a/android/app/src/com/android/bluetooth/avrcp/AvrcpBipObexServer.java
+++ b/android/app/src/com/android/bluetooth/avrcp/AvrcpBipObexServer.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/android/app/src/com/android/bluetooth/avrcp/AvrcpCoverArtService.java b/android/app/src/com/android/bluetooth/avrcp/AvrcpCoverArtService.java
index 2351f30fc2..7f8823ea35 100644
--- a/android/app/src/com/android/bluetooth/avrcp/AvrcpCoverArtService.java
+++ b/android/app/src/com/android/bluetooth/avrcp/AvrcpCoverArtService.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/android/app/src/com/android/bluetooth/avrcp/AvrcpCoverArtStorage.java b/android/app/src/com/android/bluetooth/avrcp/AvrcpCoverArtStorage.java
index cd97e9970c..4146139a12 100644
--- a/android/app/src/com/android/bluetooth/avrcp/AvrcpCoverArtStorage.java
+++ b/android/app/src/com/android/bluetooth/avrcp/AvrcpCoverArtStorage.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/android/app/src/com/android/bluetooth/avrcp/AvrcpNativeInterface.java b/android/app/src/com/android/bluetooth/avrcp/AvrcpNativeInterface.java
index 1e2e5607cb..720ce84dd8 100644
--- a/android/app/src/com/android/bluetooth/avrcp/AvrcpNativeInterface.java
+++ b/android/app/src/com/android/bluetooth/avrcp/AvrcpNativeInterface.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 The Android Open Source Project
+ * Copyright (C) 2018 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.
diff --git a/android/app/src/com/android/bluetooth/avrcp/AvrcpTargetService.java b/android/app/src/com/android/bluetooth/avrcp/AvrcpTargetService.java
index 29e6e6676b..81667dca2c 100644
--- a/android/app/src/com/android/bluetooth/avrcp/AvrcpTargetService.java
+++ b/android/app/src/com/android/bluetooth/avrcp/AvrcpTargetService.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 The Android Open Source Project
+ * Copyright (C) 2018 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.
@@ -36,7 +36,6 @@ import android.util.Log;
import android.view.KeyEvent;
import com.android.bluetooth.BluetoothEventLogger;
-import com.android.bluetooth.BluetoothMetricsProto;
import com.android.bluetooth.a2dp.A2dpService;
import com.android.bluetooth.audio_util.ListItem;
import com.android.bluetooth.audio_util.MediaData;
@@ -47,7 +46,6 @@ import com.android.bluetooth.audio_util.PlayStatus;
import com.android.bluetooth.audio_util.PlayerInfo;
import com.android.bluetooth.audio_util.PlayerSettingsManager;
import com.android.bluetooth.btservice.AdapterService;
-import com.android.bluetooth.btservice.MetricsLogger;
import com.android.bluetooth.btservice.ProfileService;
import com.android.bluetooth.btservice.ServiceFactory;
import com.android.bluetooth.flags.Flags;
@@ -308,7 +306,6 @@ public class AvrcpTargetService extends ProfileService {
void deviceConnected(BluetoothDevice device, boolean absoluteVolume) {
Log.i(TAG, "deviceConnected: device=" + device + " absoluteVolume=" + absoluteVolume);
mVolumeManager.deviceConnected(device, absoluteVolume);
- MetricsLogger.logProfileConnectionEvent(BluetoothMetricsProto.ProfileId.AVRCP);
}
/** Informs {@link AvrcpVolumeManager} that a device is disconnected */
diff --git a/android/app/src/com/android/bluetooth/avrcp/AvrcpVolumeManager.java b/android/app/src/com/android/bluetooth/avrcp/AvrcpVolumeManager.java
index 91f602815a..010538116f 100644
--- a/android/app/src/com/android/bluetooth/avrcp/AvrcpVolumeManager.java
+++ b/android/app/src/com/android/bluetooth/avrcp/AvrcpVolumeManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 The Android Open Source Project
+ * Copyright (C) 2018 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.
@@ -34,6 +34,7 @@ import com.android.bluetooth.btservice.AdapterService;
import com.android.internal.annotations.VisibleForTesting;
import java.util.HashMap;
+import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
@@ -458,8 +459,12 @@ class AvrcpVolumeManager extends AudioDeviceCallback {
if (value instanceof Integer) {
sb.append(
String.format(
+ Locale.ROOT,
" %-17s : %-14s : %3d : %s\n",
- d.getAddress(), deviceName, (Integer) value, absoluteVolume));
+ d.getAddress(),
+ deviceName,
+ (Integer) value,
+ absoluteVolume));
}
}
diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerNativeInterface.java b/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerNativeInterface.java
index 0b29c00f3e..345c4ef4d7 100644
--- a/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerNativeInterface.java
+++ b/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerNativeInterface.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 The Android Open Source Project
+ * Copyright (C) 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.
diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerService.java b/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerService.java
index 4551f320da..c4ef6a2437 100644
--- a/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerService.java
+++ b/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerService.java
@@ -16,19 +16,14 @@
package com.android.bluetooth.avrcpcontroller;
-import static android.Manifest.permission.BLUETOOTH_CONNECT;
import static android.bluetooth.BluetoothProfile.STATE_CONNECTED;
import static android.bluetooth.BluetoothProfile.STATE_CONNECTING;
import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTED;
import static java.util.Objects.requireNonNull;
-import android.annotation.RequiresPermission;
import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothAvrcpPlayerSettings;
import android.bluetooth.BluetoothDevice;
-import android.bluetooth.IBluetoothAvrcpController;
-import android.content.AttributionSource;
import android.content.Intent;
import android.media.AudioManager;
import android.support.v4.media.MediaBrowserCompat.MediaItem;
@@ -46,7 +41,6 @@ import com.android.internal.annotations.VisibleForTesting;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.UUID;
@@ -368,90 +362,6 @@ public class AvrcpControllerService extends ProfileService {
return new AvrcpControllerServiceBinder(this);
}
- // Binder object: Must be static class or memory leak may occur
- @VisibleForTesting
- static class AvrcpControllerServiceBinder extends IBluetoothAvrcpController.Stub
- implements IProfileServiceBinder {
- private AvrcpControllerService mService;
-
- AvrcpControllerServiceBinder(AvrcpControllerService service) {
- mService = service;
- }
-
- @Override
- public void cleanup() {
- mService = null;
- }
-
- @RequiresPermission(BLUETOOTH_CONNECT)
- private AvrcpControllerService getService(AttributionSource source) {
- // Cache mService because it can change while getService is called
- AvrcpControllerService service = mService;
-
- if (Utils.isInstrumentationTestMode()) {
- return service;
- }
-
- if (!Utils.checkServiceAvailable(service, TAG)
- || !Utils.checkCallerIsSystemOrActiveOrManagedUser(service, TAG)
- || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
- return null;
- }
-
- return service;
- }
-
- @Override
- public List<BluetoothDevice> getConnectedDevices(AttributionSource source) {
- AvrcpControllerService service = getService(source);
- if (service == null) {
- return Collections.emptyList();
- }
- return service.getConnectedDevices();
- }
-
- @Override
- public List<BluetoothDevice> getDevicesMatchingConnectionStates(
- int[] states, AttributionSource source) {
- AvrcpControllerService service = getService(source);
- if (service == null) {
- return Collections.emptyList();
- }
- return service.getDevicesMatchingConnectionStates(states);
- }
-
- @Override
- public int getConnectionState(BluetoothDevice device, AttributionSource source) {
- AvrcpControllerService service = getService(source);
- if (service == null) {
- return STATE_DISCONNECTED;
- }
- return service.getConnectionState(device);
- }
-
- @Override
- public void sendGroupNavigationCmd(
- BluetoothDevice device, int keyCode, int keyState, AttributionSource source) {
- getService(source);
- Log.w(TAG, "sendGroupNavigationCmd not implemented");
- }
-
- @Override
- public void setPlayerApplicationSetting(
- BluetoothAvrcpPlayerSettings settings, AttributionSource source) {
- getService(source);
- Log.w(TAG, "setPlayerApplicationSetting not implemented");
- }
-
- @Override
- public BluetoothAvrcpPlayerSettings getPlayerSettings(
- BluetoothDevice device, AttributionSource source) {
- getService(source);
- Log.w(TAG, "getPlayerSettings not implemented");
- return null;
- }
- }
-
// Called by JNI when a device has connected or disconnected.
@VisibleForTesting
synchronized void onConnectionStateChanged(
diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerServiceBinder.java b/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerServiceBinder.java
new file mode 100644
index 0000000000..105e9a8709
--- /dev/null
+++ b/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerServiceBinder.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.bluetooth.avrcpcontroller;
+
+import static android.Manifest.permission.BLUETOOTH_CONNECT;
+import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTED;
+
+import android.annotation.RequiresPermission;
+import android.bluetooth.BluetoothAvrcpPlayerSettings;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.IBluetoothAvrcpController;
+import android.content.AttributionSource;
+import android.util.Log;
+
+import com.android.bluetooth.Utils;
+import com.android.bluetooth.btservice.ProfileService.IProfileServiceBinder;
+
+import java.util.Collections;
+import java.util.List;
+
+class AvrcpControllerServiceBinder extends IBluetoothAvrcpController.Stub
+ implements IProfileServiceBinder {
+ private static final String TAG = AvrcpControllerServiceBinder.class.getSimpleName();
+
+ private AvrcpControllerService mService;
+
+ AvrcpControllerServiceBinder(AvrcpControllerService service) {
+ mService = service;
+ }
+
+ @Override
+ public void cleanup() {
+ mService = null;
+ }
+
+ @RequiresPermission(BLUETOOTH_CONNECT)
+ private AvrcpControllerService getService(AttributionSource source) {
+ AvrcpControllerService service = mService;
+
+ if (Utils.isInstrumentationTestMode()) {
+ return service;
+ }
+
+ if (!Utils.checkServiceAvailable(service, TAG)
+ || !Utils.checkCallerIsSystemOrActiveOrManagedUser(service, TAG)
+ || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
+ return null;
+ }
+
+ return service;
+ }
+
+ @Override
+ public List<BluetoothDevice> getConnectedDevices(AttributionSource source) {
+ AvrcpControllerService service = getService(source);
+ if (service == null) {
+ return Collections.emptyList();
+ }
+ return service.getConnectedDevices();
+ }
+
+ @Override
+ public List<BluetoothDevice> getDevicesMatchingConnectionStates(
+ int[] states, AttributionSource source) {
+ AvrcpControllerService service = getService(source);
+ if (service == null) {
+ return Collections.emptyList();
+ }
+ return service.getDevicesMatchingConnectionStates(states);
+ }
+
+ @Override
+ public int getConnectionState(BluetoothDevice device, AttributionSource source) {
+ AvrcpControllerService service = getService(source);
+ if (service == null) {
+ return STATE_DISCONNECTED;
+ }
+ return service.getConnectionState(device);
+ }
+
+ @Override
+ public void sendGroupNavigationCmd(
+ BluetoothDevice device, int keyCode, int keyState, AttributionSource source) {
+ getService(source);
+ Log.w(TAG, "sendGroupNavigationCmd not implemented");
+ }
+
+ @Override
+ public void setPlayerApplicationSetting(
+ BluetoothAvrcpPlayerSettings settings, AttributionSource source) {
+ getService(source);
+ Log.w(TAG, "setPlayerApplicationSetting not implemented");
+ }
+
+ @Override
+ public BluetoothAvrcpPlayerSettings getPlayerSettings(
+ BluetoothDevice device, AttributionSource source) {
+ getService(source);
+ Log.w(TAG, "getPlayerSettings not implemented");
+ return null;
+ }
+}
diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerStateMachine.java b/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerStateMachine.java
index a74ec6c0e9..8b987e301d 100644
--- a/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerStateMachine.java
+++ b/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerStateMachine.java
@@ -38,12 +38,10 @@ import android.support.v4.media.session.PlaybackStateCompat;
import android.util.Log;
import android.util.SparseArray;
-import com.android.bluetooth.BluetoothMetricsProto;
import com.android.bluetooth.R;
import com.android.bluetooth.Utils;
import com.android.bluetooth.a2dpsink.A2dpSinkService;
import com.android.bluetooth.btservice.AdapterService;
-import com.android.bluetooth.btservice.MetricsLogger;
import com.android.bluetooth.btservice.ProfileService;
import com.android.bluetooth.flags.Flags;
import com.android.internal.annotations.VisibleForTesting;
@@ -1405,10 +1403,7 @@ class AvrcpControllerStateMachine extends StateMachine {
if (mMostRecentState == currentState) {
return;
}
- if (currentState == STATE_CONNECTED) {
- MetricsLogger.logProfileConnectionEvent(
- BluetoothMetricsProto.ProfileId.AVRCP_CONTROLLER);
- }
+
mAdapterService.updateProfileConnectionAdapterProperties(
mDevice, BluetoothProfile.AVRCP_CONTROLLER, currentState, mMostRecentState);
diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/ParseException.java b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/ParseException.java
index bd23be2972..ee00cef211 100644
--- a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/ParseException.java
+++ b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/ParseException.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/android/app/src/com/android/bluetooth/bas/BatteryService.java b/android/app/src/com/android/bluetooth/bas/BatteryService.java
index ac5eaab2f9..0b32dbf837 100644
--- a/android/app/src/com/android/bluetooth/bas/BatteryService.java
+++ b/android/app/src/com/android/bluetooth/bas/BatteryService.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/src/com/android/bluetooth/bas/BatteryStateMachine.java b/android/app/src/com/android/bluetooth/bas/BatteryStateMachine.java
index 991a77cb93..62be4fb838 100644
--- a/android/app/src/com/android/bluetooth/bas/BatteryStateMachine.java
+++ b/android/app/src/com/android/bluetooth/bas/BatteryStateMachine.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/src/com/android/bluetooth/bass_client/BaseData.java b/android/app/src/com/android/bluetooth/bass_client/BaseData.java
index 8f63aecc14..200bfe76a3 100644
--- a/android/app/src/com/android/bluetooth/bass_client/BaseData.java
+++ b/android/app/src/com/android/bluetooth/bass_client/BaseData.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/src/com/android/bluetooth/bass_client/BassClientPeriodicAdvertisingManager.java b/android/app/src/com/android/bluetooth/bass_client/BassClientPeriodicAdvertisingManager.java
index 28d9f79d12..f54fc44c1a 100644
--- a/android/app/src/com/android/bluetooth/bass_client/BassClientPeriodicAdvertisingManager.java
+++ b/android/app/src/com/android/bluetooth/bass_client/BassClientPeriodicAdvertisingManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 The Android Open Source Project
+ * Copyright (C) 2024 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.
diff --git a/android/app/src/com/android/bluetooth/bass_client/BassClientService.java b/android/app/src/com/android/bluetooth/bass_client/BassClientService.java
index be55eff42b..42528676b4 100644
--- a/android/app/src/com/android/bluetooth/bass_client/BassClientService.java
+++ b/android/app/src/com/android/bluetooth/bass_client/BassClientService.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -16,9 +16,6 @@
package com.android.bluetooth.bass_client;
-import static android.Manifest.permission.BLUETOOTH_CONNECT;
-import static android.Manifest.permission.BLUETOOTH_PRIVILEGED;
-import static android.Manifest.permission.BLUETOOTH_SCAN;
import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_ALLOWED;
import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_UNKNOWN;
@@ -36,7 +33,6 @@ import static com.android.bluetooth.flags.Flags.leaudioSortScansToSyncByFails;
import static java.util.Objects.requireNonNull;
-import android.annotation.RequiresPermission;
import android.annotation.SuppressLint;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
@@ -50,7 +46,6 @@ import android.bluetooth.BluetoothLeBroadcastSubgroup;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothStatusCodes;
import android.bluetooth.BluetoothUuid;
-import android.bluetooth.IBluetoothLeBroadcastAssistant;
import android.bluetooth.IBluetoothLeBroadcastAssistantCallback;
import android.bluetooth.le.IScannerCallback;
import android.bluetooth.le.PeriodicAdvertisingCallback;
@@ -60,7 +55,6 @@ import android.bluetooth.le.ScanFilter;
import android.bluetooth.le.ScanRecord;
import android.bluetooth.le.ScanResult;
import android.bluetooth.le.ScanSettings;
-import android.content.AttributionSource;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
@@ -737,7 +731,7 @@ public class BassClientService extends ProfileService {
@Override
protected IProfileServiceBinder initBinder() {
- return new BluetoothLeBroadcastAssistantBinder(this);
+ return new BassClientServiceBinder(this);
}
@Override
@@ -1803,7 +1797,6 @@ public class BassClientService extends ProfileService {
devices.add(sm.getDevice());
}
}
- log("getConnectedDevices: " + devices);
return devices;
}
}
@@ -2763,13 +2756,6 @@ public class BassClientService extends ProfileService {
}
void addSelectSourceRequest(int broadcastId, boolean hasPriority) {
- sEventLogger.logd(
- TAG,
- "Add Select Broadcast Source, broadcastId: "
- + broadcastId
- + ", hasPriority: "
- + hasPriority);
-
if (getActiveSyncedSources().contains(getSyncHandleForBroadcastId(broadcastId))) {
log("addSelectSourceRequest: Already synced");
return;
@@ -2780,6 +2766,13 @@ public class BassClientService extends ProfileService {
return;
}
+ sEventLogger.logd(
+ TAG,
+ "Add Select Broadcast Source, broadcastId: "
+ + broadcastId
+ + ", hasPriority: "
+ + hasPriority);
+
ScanResult scanRes = getCachedBroadcast(broadcastId);
if (scanRes == null) {
log("addSelectSourceRequest: ScanResult empty");
@@ -3467,25 +3460,6 @@ public class BassClientService extends ProfileService {
*
* @param sink representing the Broadcast Sink from which a Broadcast Source should be removed
* @param sourceId source ID as delivered in onSourceAdded
- */
- private void removeSourceInternal(BluetoothDevice sink, int sourceId) {
- log("removeSourceInternal prepare: device: " + sink + ", sourceId: " + sourceId);
-
- BassClientStateMachine stateMachine = getOrCreateStateMachine(sink);
- int statusCode = validateParametersForSourceOperation(stateMachine, sink, sourceId);
- if (statusCode != BluetoothStatusCodes.SUCCESS) {
- mCallbacks.notifySourceRemoveFailed(sink, sourceId, statusCode);
- return;
- }
- BluetoothLeBroadcastMetadata metaData = stateMachine.getCurrentBroadcastMetadata(sourceId);
- removeSourceInternal(sink, sourceId, stateMachine, metaData);
- }
-
- /**
- * Removes the Broadcast Source from a single Broadcast Sink
- *
- * @param sink representing the Broadcast Sink from which a Broadcast Source should be removed
- * @param sourceId source ID as delivered in onSourceAdded
* @param stateMachine stateMachine for this sink
* @param metaData current broadcast metadata for this sink
*/
@@ -3542,7 +3516,6 @@ public class BassClientService extends ProfileService {
* @return the list of Broadcast Receive State {@link BluetoothLeBroadcastReceiveState}
*/
public List<BluetoothLeBroadcastReceiveState> getAllSources(BluetoothDevice sink) {
- log("getAllSources for " + sink);
synchronized (mStateMachines) {
BassClientStateMachine stateMachine = getOrCreateStateMachine(sink);
if (stateMachine == null) {
@@ -3688,9 +3661,9 @@ public class BassClientService extends ProfileService {
* @param broadcastId The broadcast ID for which the receivers should be stopped or suspended
*/
private void suspendSourceReceivers(int broadcastId) {
- log("stopSourceReceivers broadcastId: " + broadcastId);
+ log("suspendSourceReceivers broadcastId: " + broadcastId);
- Map<BluetoothDevice, Integer> sourcesToRemove = new HashMap<>();
+ List<Pair<BluetoothDevice, Integer>> sourcesToModify = new ArrayList<>();
HashSet<Integer> broadcastIdsToStopMonitoring = new HashSet<>();
for (BluetoothDevice device : getConnectedDevices()) {
if (!leaudioBroadcastResyncHelper()) {
@@ -3711,7 +3684,8 @@ public class BassClientService extends ProfileService {
sEventLogger.logd(TAG, "Add broadcast sink to paused cache: " + device);
mPausedBroadcastSinks.add(device);
- sourcesToRemove.put(device, receiveState.getSourceId());
+ sourcesToModify.add(
+ new Pair<BluetoothDevice, Integer>(device, receiveState.getSourceId()));
}
} else {
for (BluetoothLeBroadcastReceiveState receiveState : getAllSources(device)) {
@@ -3725,11 +3699,8 @@ public class BassClientService extends ProfileService {
broadcastIdsToStopMonitoring.add(receiveState.getBroadcastId());
- if (!mPausedBroadcastSinks.contains(device)
- || isSinkUnintentionalPauseType(receiveState.getBroadcastId())) {
- // Remove device if not paused yet
- sourcesToRemove.put(device, receiveState.getSourceId());
- }
+ sourcesToModify.add(
+ new Pair<BluetoothDevice, Integer>(device, receiveState.getSourceId()));
sEventLogger.logd(TAG, "Add broadcast sink to paused cache: " + device);
mPausedBroadcastSinks.add(device);
@@ -3741,8 +3712,35 @@ public class BassClientService extends ProfileService {
stopBigMonitoring(broadcastIdToStopMonitoring, /* hostInitiated */ true);
}
- for (Map.Entry<BluetoothDevice, Integer> entry : sourcesToRemove.entrySet()) {
- removeSourceInternal(entry.getKey(), entry.getValue());
+ /* Suspend all previously marked sources with modify source operation */
+ for (Pair<BluetoothDevice, Integer> pair : sourcesToModify) {
+ BluetoothDevice device = pair.first;
+
+ BassClientStateMachine sm = mStateMachines.get(device);
+ if (sm == null) {
+ Log.e(
+ TAG,
+ "suspendSourceReceivers: invalid state machine for device: " + pair.first);
+ continue;
+ }
+
+ int sourceId = pair.second;
+ int paSyncValue = BassConstants.PA_SYNC_DO_NOT_SYNC;
+ BluetoothLeBroadcastMetadata metadata = sm.getCurrentBroadcastMetadata(sourceId);
+
+ sEventLogger.logd(
+ TAG,
+ "Modify Broadcast Source: "
+ + ("device: " + device)
+ + (", sourceId: " + sourceId)
+ + (", PA sync value: " + paSyncValue)
+ + (", updatedBroadcastId: " + metadata.getBroadcastId())
+ + (", updatedBroadcastName: " + metadata.getBroadcastName()));
+ Message message = sm.obtainMessage(BassClientStateMachine.UPDATE_BCAST_SOURCE);
+ message.arg1 = sourceId;
+ message.arg2 = paSyncValue;
+ message.obj = metadata;
+ sm.sendMessage(message);
}
if (leaudioBroadcastResyncHelper()) {
@@ -4825,234 +4823,4 @@ public class BassClientService extends ProfileService {
sEventLogger.dump(sb);
sb.append("\n");
}
-
- /** Binder object: must be a static class or memory leak may occur */
- @VisibleForTesting
- static class BluetoothLeBroadcastAssistantBinder extends IBluetoothLeBroadcastAssistant.Stub
- implements IProfileServiceBinder {
- BassClientService mService;
-
- BluetoothLeBroadcastAssistantBinder(BassClientService svc) {
- mService = svc;
- }
-
- @Override
- public void cleanup() {
- mService = null;
- }
-
- @RequiresPermission(allOf = {BLUETOOTH_CONNECT, BLUETOOTH_PRIVILEGED})
- private BassClientService getServiceAndEnforceConnect(AttributionSource source) {
- // Cache mService because it can change while getService is called
- BassClientService service = mService;
-
- if (Utils.isInstrumentationTestMode()) {
- return service;
- }
-
- if (!Utils.checkServiceAvailable(service, TAG)
- || !Utils.checkCallerIsSystemOrActiveOrManagedUser(service, TAG)
- || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
- return null;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- return service;
- }
-
- @RequiresPermission(allOf = {BLUETOOTH_SCAN, BLUETOOTH_PRIVILEGED})
- private BassClientService getServiceAndEnforceScan(AttributionSource source) {
- // Cache mService because it can change while getService is called
- BassClientService service = mService;
-
- if (Utils.isInstrumentationTestMode()) {
- return service;
- }
-
- if (!Utils.checkServiceAvailable(service, TAG)
- || !Utils.checkCallerIsSystemOrActiveOrManagedUser(service, TAG)
- || !Utils.checkScanPermissionForDataDelivery(service, source, TAG)) {
- return null;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- return service;
- }
-
- @Override
- public int getConnectionState(BluetoothDevice sink, AttributionSource source) {
- BassClientService service = getServiceAndEnforceConnect(source);
- if (service == null) {
- Log.e(TAG, "Service is null");
- return STATE_DISCONNECTED;
- }
- return service.getConnectionState(sink);
- }
-
- @Override
- public List<BluetoothDevice> getDevicesMatchingConnectionStates(
- int[] states, AttributionSource source) {
- BassClientService service = getServiceAndEnforceConnect(source);
- if (service == null) {
- Log.e(TAG, "Service is null");
- return Collections.emptyList();
- }
- return service.getDevicesMatchingConnectionStates(states);
- }
-
- @Override
- public List<BluetoothDevice> getConnectedDevices(AttributionSource source) {
- BassClientService service = getServiceAndEnforceConnect(source);
- if (service == null) {
- Log.e(TAG, "Service is null");
- return Collections.emptyList();
- }
- return service.getConnectedDevices();
- }
-
- @Override
- public boolean setConnectionPolicy(
- BluetoothDevice device, int connectionPolicy, AttributionSource source) {
- BassClientService service = getServiceAndEnforceConnect(source);
- if (service == null) {
- Log.e(TAG, "Service is null");
- return false;
- }
- return service.setConnectionPolicy(device, connectionPolicy);
- }
-
- @Override
- public int getConnectionPolicy(BluetoothDevice device, AttributionSource source) {
- BassClientService service = getServiceAndEnforceConnect(source);
- if (service == null) {
- Log.e(TAG, "Service is null");
- return CONNECTION_POLICY_FORBIDDEN;
- }
- return service.getConnectionPolicy(device);
- }
-
- @Override
- public void registerCallback(
- IBluetoothLeBroadcastAssistantCallback cb, AttributionSource source) {
- BassClientService service = getServiceAndEnforceConnect(source);
- if (service == null) {
- Log.e(TAG, "Service is null");
- return;
- }
- service.registerCallback(cb);
- }
-
- @Override
- public void unregisterCallback(
- IBluetoothLeBroadcastAssistantCallback cb, AttributionSource source) {
- BassClientService service = getServiceAndEnforceConnect(source);
- if (service == null) {
- Log.e(TAG, "Service is null");
- return;
- }
- service.unregisterCallback(cb);
- }
-
- @Override
- public void startSearchingForSources(List<ScanFilter> filters, AttributionSource source) {
- BassClientService service = getServiceAndEnforceScan(source);
- if (service == null) {
- Log.e(TAG, "Service is null");
- return;
- }
- service.startSearchingForSources(filters);
- }
-
- @Override
- public void stopSearchingForSources(AttributionSource source) {
- BassClientService service = getServiceAndEnforceScan(source);
- if (service == null) {
- Log.e(TAG, "Service is null");
- return;
- }
- service.stopSearchingForSources();
- }
-
- @Override
- public boolean isSearchInProgress(AttributionSource source) {
- BassClientService service = getServiceAndEnforceScan(source);
- if (service == null) {
- Log.e(TAG, "Service is null");
- return false;
- }
- return service.isSearchInProgress();
- }
-
- @Override
- public void addSource(
- BluetoothDevice sink,
- BluetoothLeBroadcastMetadata sourceMetadata,
- boolean isGroupOp,
- AttributionSource source) {
- BassClientService service = getServiceAndEnforceConnect(source);
- if (service == null) {
- Log.e(TAG, "Service is null");
- return;
- }
- service.addSource(sink, sourceMetadata, isGroupOp);
- }
-
- @Override
- public void modifySource(
- BluetoothDevice sink,
- int sourceId,
- BluetoothLeBroadcastMetadata updatedMetadata,
- AttributionSource source) {
- BassClientService service = getServiceAndEnforceConnect(source);
- if (service == null) {
- Log.e(TAG, "Service is null");
- return;
- }
- service.modifySource(sink, sourceId, updatedMetadata);
- }
-
- @Override
- public void removeSource(BluetoothDevice sink, int sourceId, AttributionSource source) {
- BassClientService service = getServiceAndEnforceConnect(source);
- if (service == null) {
- Log.e(TAG, "Service is null");
- return;
- }
- service.removeSource(sink, sourceId);
- }
-
- @Override
- public List<BluetoothLeBroadcastReceiveState> getAllSources(
- BluetoothDevice sink, AttributionSource source) {
- BassClientService service = getServiceAndEnforceConnect(source);
- if (service == null) {
- Log.e(TAG, "Service is null");
- return Collections.emptyList();
- }
- return service.getAllSources(sink);
- }
-
- @Override
- public int getMaximumSourceCapacity(BluetoothDevice sink, AttributionSource source) {
- BassClientService service = getServiceAndEnforceConnect(source);
- if (service == null) {
- Log.e(TAG, "Service is null");
- return 0;
- }
- return service.getMaximumSourceCapacity(sink);
- }
-
- @Override
- public BluetoothLeBroadcastMetadata getSourceMetadata(
- BluetoothDevice sink, int sourceId, AttributionSource source) {
- BassClientService service = getServiceAndEnforceConnect(source);
- if (service == null) {
- Log.e(TAG, "Service is null");
- return null;
- }
- return service.getSourceMetadata(sink, sourceId);
- }
- }
}
diff --git a/android/app/src/com/android/bluetooth/bass_client/BassClientServiceBinder.java b/android/app/src/com/android/bluetooth/bass_client/BassClientServiceBinder.java
new file mode 100644
index 0000000000..d319e6ed47
--- /dev/null
+++ b/android/app/src/com/android/bluetooth/bass_client/BassClientServiceBinder.java
@@ -0,0 +1,268 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.bluetooth.bass_client;
+
+import static android.Manifest.permission.BLUETOOTH_CONNECT;
+import static android.Manifest.permission.BLUETOOTH_PRIVILEGED;
+import static android.Manifest.permission.BLUETOOTH_SCAN;
+import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
+import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTED;
+
+import android.annotation.RequiresPermission;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothLeBroadcastMetadata;
+import android.bluetooth.BluetoothLeBroadcastReceiveState;
+import android.bluetooth.IBluetoothLeBroadcastAssistant;
+import android.bluetooth.IBluetoothLeBroadcastAssistantCallback;
+import android.bluetooth.le.ScanFilter;
+import android.content.AttributionSource;
+import android.util.Log;
+
+import com.android.bluetooth.Utils;
+import com.android.bluetooth.btservice.ProfileService.IProfileServiceBinder;
+
+import java.util.Collections;
+import java.util.List;
+
+class BassClientServiceBinder extends IBluetoothLeBroadcastAssistant.Stub
+ implements IProfileServiceBinder {
+ private static final String TAG = BassClientServiceBinder.class.getSimpleName();
+
+ private BassClientService mService;
+
+ BassClientServiceBinder(BassClientService svc) {
+ mService = svc;
+ }
+
+ @Override
+ public void cleanup() {
+ mService = null;
+ }
+
+ @RequiresPermission(allOf = {BLUETOOTH_CONNECT, BLUETOOTH_PRIVILEGED})
+ private BassClientService getServiceAndEnforceConnect(AttributionSource source) {
+ BassClientService service = mService;
+
+ if (Utils.isInstrumentationTestMode()) {
+ return service;
+ }
+
+ if (!Utils.checkServiceAvailable(service, TAG)
+ || !Utils.checkCallerIsSystemOrActiveOrManagedUser(service, TAG)
+ || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
+ return null;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+
+ return service;
+ }
+
+ @RequiresPermission(allOf = {BLUETOOTH_SCAN, BLUETOOTH_PRIVILEGED})
+ private BassClientService getServiceAndEnforceScan(AttributionSource source) {
+ BassClientService service = mService;
+
+ if (Utils.isInstrumentationTestMode()) {
+ return service;
+ }
+
+ if (!Utils.checkServiceAvailable(service, TAG)
+ || !Utils.checkCallerIsSystemOrActiveOrManagedUser(service, TAG)
+ || !Utils.checkScanPermissionForDataDelivery(
+ service, source, TAG, "getServiceAndEnforceScan")) {
+ return null;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+
+ return service;
+ }
+
+ @Override
+ public int getConnectionState(BluetoothDevice sink, AttributionSource source) {
+ BassClientService service = getServiceAndEnforceConnect(source);
+ if (service == null) {
+ Log.e(TAG, "Service is null");
+ return STATE_DISCONNECTED;
+ }
+ return service.getConnectionState(sink);
+ }
+
+ @Override
+ public List<BluetoothDevice> getDevicesMatchingConnectionStates(
+ int[] states, AttributionSource source) {
+ BassClientService service = getServiceAndEnforceConnect(source);
+ if (service == null) {
+ Log.e(TAG, "Service is null");
+ return Collections.emptyList();
+ }
+ return service.getDevicesMatchingConnectionStates(states);
+ }
+
+ @Override
+ public List<BluetoothDevice> getConnectedDevices(AttributionSource source) {
+ BassClientService service = getServiceAndEnforceConnect(source);
+ if (service == null) {
+ Log.e(TAG, "Service is null");
+ return Collections.emptyList();
+ }
+ return service.getConnectedDevices();
+ }
+
+ @Override
+ public boolean setConnectionPolicy(
+ BluetoothDevice device, int connectionPolicy, AttributionSource source) {
+ BassClientService service = getServiceAndEnforceConnect(source);
+ if (service == null) {
+ Log.e(TAG, "Service is null");
+ return false;
+ }
+ return service.setConnectionPolicy(device, connectionPolicy);
+ }
+
+ @Override
+ public int getConnectionPolicy(BluetoothDevice device, AttributionSource source) {
+ BassClientService service = getServiceAndEnforceConnect(source);
+ if (service == null) {
+ Log.e(TAG, "Service is null");
+ return CONNECTION_POLICY_FORBIDDEN;
+ }
+ return service.getConnectionPolicy(device);
+ }
+
+ @Override
+ public void registerCallback(
+ IBluetoothLeBroadcastAssistantCallback cb, AttributionSource source) {
+ BassClientService service = getServiceAndEnforceConnect(source);
+ if (service == null) {
+ Log.e(TAG, "Service is null");
+ return;
+ }
+ service.registerCallback(cb);
+ }
+
+ @Override
+ public void unregisterCallback(
+ IBluetoothLeBroadcastAssistantCallback cb, AttributionSource source) {
+ BassClientService service = getServiceAndEnforceConnect(source);
+ if (service == null) {
+ Log.e(TAG, "Service is null");
+ return;
+ }
+ service.unregisterCallback(cb);
+ }
+
+ @Override
+ public void startSearchingForSources(List<ScanFilter> filters, AttributionSource source) {
+ BassClientService service = getServiceAndEnforceScan(source);
+ if (service == null) {
+ Log.e(TAG, "Service is null");
+ return;
+ }
+ service.startSearchingForSources(filters);
+ }
+
+ @Override
+ public void stopSearchingForSources(AttributionSource source) {
+ BassClientService service = getServiceAndEnforceScan(source);
+ if (service == null) {
+ Log.e(TAG, "Service is null");
+ return;
+ }
+ service.stopSearchingForSources();
+ }
+
+ @Override
+ public boolean isSearchInProgress(AttributionSource source) {
+ BassClientService service = getServiceAndEnforceScan(source);
+ if (service == null) {
+ Log.e(TAG, "Service is null");
+ return false;
+ }
+ return service.isSearchInProgress();
+ }
+
+ @Override
+ public void addSource(
+ BluetoothDevice sink,
+ BluetoothLeBroadcastMetadata sourceMetadata,
+ boolean isGroupOp,
+ AttributionSource source) {
+ BassClientService service = getServiceAndEnforceConnect(source);
+ if (service == null) {
+ Log.e(TAG, "Service is null");
+ return;
+ }
+ service.addSource(sink, sourceMetadata, isGroupOp);
+ }
+
+ @Override
+ public void modifySource(
+ BluetoothDevice sink,
+ int sourceId,
+ BluetoothLeBroadcastMetadata updatedMetadata,
+ AttributionSource source) {
+ BassClientService service = getServiceAndEnforceConnect(source);
+ if (service == null) {
+ Log.e(TAG, "Service is null");
+ return;
+ }
+ service.modifySource(sink, sourceId, updatedMetadata);
+ }
+
+ @Override
+ public void removeSource(BluetoothDevice sink, int sourceId, AttributionSource source) {
+ BassClientService service = getServiceAndEnforceConnect(source);
+ if (service == null) {
+ Log.e(TAG, "Service is null");
+ return;
+ }
+ service.removeSource(sink, sourceId);
+ }
+
+ @Override
+ public List<BluetoothLeBroadcastReceiveState> getAllSources(
+ BluetoothDevice sink, AttributionSource source) {
+ BassClientService service = getServiceAndEnforceConnect(source);
+ if (service == null) {
+ Log.e(TAG, "Service is null");
+ return Collections.emptyList();
+ }
+ return service.getAllSources(sink);
+ }
+
+ @Override
+ public int getMaximumSourceCapacity(BluetoothDevice sink, AttributionSource source) {
+ BassClientService service = getServiceAndEnforceConnect(source);
+ if (service == null) {
+ Log.e(TAG, "Service is null");
+ return 0;
+ }
+ return service.getMaximumSourceCapacity(sink);
+ }
+
+ @Override
+ public BluetoothLeBroadcastMetadata getSourceMetadata(
+ BluetoothDevice sink, int sourceId, AttributionSource source) {
+ BassClientService service = getServiceAndEnforceConnect(source);
+ if (service == null) {
+ Log.e(TAG, "Service is null");
+ return null;
+ }
+ return service.getSourceMetadata(sink, sourceId);
+ }
+}
diff --git a/android/app/src/com/android/bluetooth/bass_client/BassClientStateMachine.java b/android/app/src/com/android/bluetooth/bass_client/BassClientStateMachine.java
index 00278b95df..2ebcd5d5d2 100644
--- a/android/app/src/com/android/bluetooth/bass_client/BassClientStateMachine.java
+++ b/android/app/src/com/android/bluetooth/bass_client/BassClientStateMachine.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -450,9 +450,8 @@ class BassClientStateMachine extends StateMachine {
if (state == BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_SYNCINFO_REQUEST) {
log("Initiate PAST procedure");
int sourceId = recvState.getSourceId();
- BluetoothLeBroadcastMetadata currentMetadata = getCurrentBroadcastMetadata(sourceId);
- if (mService.isLocalBroadcast(currentMetadata)) {
- int advHandle = currentMetadata.getSourceAdvertisingSid();
+ if (mService.isLocalBroadcast(recvState)) {
+ int advHandle = recvState.getSourceAdvertisingSid();
serviceData = 0x000000FF & sourceId;
serviceData = serviceData << 8;
// Address we set in the Source Address can differ from the address in the air
@@ -812,8 +811,8 @@ class BassClientStateMachine extends StateMachine {
}
if (leaudioBroadcastResyncHelper()) {
// Notify service BASS state ready for operations
- mService.getCallbacks().notifyBassStateReady(mDevice);
mBassStateReady = true;
+ mService.getCallbacks().notifyBassStateReady(mDevice);
}
} else {
log("Updated receiver state: " + recvState);
@@ -1189,8 +1188,8 @@ class BassClientStateMachine extends StateMachine {
mNumOfReadyBroadcastReceiverStates++;
if (mNumOfReadyBroadcastReceiverStates == mNumOfBroadcastReceiverStates) {
// Notify service BASS state ready for operations
- mService.getCallbacks().notifyBassStateReady(mDevice);
mBassStateReady = true;
+ mService.getCallbacks().notifyBassStateReady(mDevice);
}
} else {
processBroadcastReceiverStateObsolete(
diff --git a/android/app/src/com/android/bluetooth/bass_client/BassConstants.java b/android/app/src/com/android/bluetooth/bass_client/BassConstants.java
index 13b0339853..e68454d829 100644
--- a/android/app/src/com/android/bluetooth/bass_client/BassConstants.java
+++ b/android/app/src/com/android/bluetooth/bass_client/BassConstants.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/src/com/android/bluetooth/bass_client/BassUtils.java b/android/app/src/com/android/bluetooth/bass_client/BassUtils.java
index 69d61ce234..f84ae4c730 100644
--- a/android/app/src/com/android/bluetooth/bass_client/BassUtils.java
+++ b/android/app/src/com/android/bluetooth/bass_client/BassUtils.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/src/com/android/bluetooth/bass_client/PeriodicAdvertisementResult.java b/android/app/src/com/android/bluetooth/bass_client/PeriodicAdvertisementResult.java
index e36f0de976..992e0a4c7e 100644
--- a/android/app/src/com/android/bluetooth/bass_client/PeriodicAdvertisementResult.java
+++ b/android/app/src/com/android/bluetooth/bass_client/PeriodicAdvertisementResult.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/src/com/android/bluetooth/bass_client/PublicBroadcastData.java b/android/app/src/com/android/bluetooth/bass_client/PublicBroadcastData.java
index 4cd4062906..536c939b59 100644
--- a/android/app/src/com/android/bluetooth/bass_client/PublicBroadcastData.java
+++ b/android/app/src/com/android/bluetooth/bass_client/PublicBroadcastData.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 The Android Open Source Project
+ * Copyright (C) 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.
diff --git a/android/app/src/com/android/bluetooth/btservice/AdapterNativeInterface.java b/android/app/src/com/android/bluetooth/btservice/AdapterNativeInterface.java
index 63d11202a1..dafcc8cecc 100644
--- a/android/app/src/com/android/bluetooth/btservice/AdapterNativeInterface.java
+++ b/android/app/src/com/android/bluetooth/btservice/AdapterNativeInterface.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 The Android Open Source Project
+ * Copyright (C) 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.
diff --git a/android/app/src/com/android/bluetooth/btservice/AdapterProperties.java b/android/app/src/com/android/bluetooth/btservice/AdapterProperties.java
index 9a5b54540d..bd483f5925 100644
--- a/android/app/src/com/android/bluetooth/btservice/AdapterProperties.java
+++ b/android/app/src/com/android/bluetooth/btservice/AdapterProperties.java
@@ -24,6 +24,8 @@ import static android.bluetooth.BluetoothProfile.STATE_CONNECTING;
import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTED;
import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTING;
+import static com.android.bluetooth.Utils.BD_ADDR_LEN;
+
import android.annotation.NonNull;
import android.app.BroadcastOptions;
import android.bluetooth.BluetoothA2dp;
@@ -79,7 +81,6 @@ class AdapterProperties {
private static final long DEFAULT_DISCOVERY_TIMEOUT_MS = 12800;
@VisibleForTesting static final int BLUETOOTH_NAME_MAX_LENGTH_BYTES = 248;
- private static final int BD_ADDR_LEN = 6; // in bytes
private static final int SYSTEM_CONNECTION_LATENCY_METRIC = 65536;
private volatile String mName;
diff --git a/android/app/src/com/android/bluetooth/btservice/AdapterService.java b/android/app/src/com/android/bluetooth/btservice/AdapterService.java
index 3b2a10d2ad..9bec63769d 100644
--- a/android/app/src/com/android/bluetooth/btservice/AdapterService.java
+++ b/android/app/src/com/android/bluetooth/btservice/AdapterService.java
@@ -20,16 +20,12 @@ package com.android.bluetooth.btservice;
import static android.Manifest.permission.BLUETOOTH_CONNECT;
import static android.Manifest.permission.BLUETOOTH_PRIVILEGED;
import static android.Manifest.permission.BLUETOOTH_SCAN;
-import static android.Manifest.permission.DUMP;
-import static android.Manifest.permission.LOCAL_MAC_ADDRESS;
-import static android.Manifest.permission.MODIFY_PHONE_STATE;
import static android.bluetooth.BluetoothAdapter.SCAN_MODE_CONNECTABLE;
import static android.bluetooth.BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE;
import static android.bluetooth.BluetoothAdapter.SCAN_MODE_NONE;
import static android.bluetooth.BluetoothAdapter.nameForState;
import static android.bluetooth.BluetoothDevice.BATTERY_LEVEL_UNKNOWN;
import static android.bluetooth.BluetoothDevice.BOND_NONE;
-import static android.bluetooth.BluetoothDevice.TRANSPORT_AUTO;
import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_ALLOWED;
import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_UNKNOWN;
@@ -42,9 +38,6 @@ import static android.bluetooth.IBluetoothLeAudio.LE_AUDIO_GROUP_ID_INVALID;
import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
import static android.text.format.DateUtils.SECOND_IN_MILLIS;
-import static com.android.bluetooth.ChangeIds.ENFORCE_CONNECT;
-import static com.android.bluetooth.Utils.callerIsSystem;
-import static com.android.bluetooth.Utils.callerIsSystemOrActiveOrManagedUser;
import static com.android.bluetooth.Utils.getBytesFromAddress;
import static com.android.bluetooth.Utils.isDualModeAudioEnabled;
import static com.android.bluetooth.Utils.isPackageNameAccurate;
@@ -60,7 +53,6 @@ import android.app.AppOpsManager;
import android.app.PendingIntent;
import android.app.Service;
import android.app.admin.DevicePolicyManager;
-import android.app.compat.CompatChanges;
import android.bluetooth.BluetoothA2dp;
import android.bluetooth.BluetoothActivityEnergyInfo;
import android.bluetooth.BluetoothAdapter;
@@ -72,7 +64,6 @@ import android.bluetooth.BluetoothFrameworkInitializer;
import android.bluetooth.BluetoothLeAudio;
import android.bluetooth.BluetoothMap;
import android.bluetooth.BluetoothProfile;
-import android.bluetooth.BluetoothProtoEnums;
import android.bluetooth.BluetoothQualityReport;
import android.bluetooth.BluetoothSap;
import android.bluetooth.BluetoothServerSocket;
@@ -82,16 +73,12 @@ import android.bluetooth.BluetoothStatusCodes;
import android.bluetooth.BluetoothUtils;
import android.bluetooth.BluetoothUuid;
import android.bluetooth.BufferConstraints;
-import android.bluetooth.IBluetooth;
-import android.bluetooth.IBluetoothActivityEnergyInfoListener;
import android.bluetooth.IBluetoothCallback;
import android.bluetooth.IBluetoothConnectionCallback;
-import android.bluetooth.IBluetoothHciVendorSpecificCallback;
import android.bluetooth.IBluetoothMetadataListener;
import android.bluetooth.IBluetoothOobDataCallback;
import android.bluetooth.IBluetoothPreferredAudioProfilesCallback;
import android.bluetooth.IBluetoothQualityReportReadyCallback;
-import android.bluetooth.IBluetoothSocketManager;
import android.bluetooth.IncomingRfcommSocketInfo;
import android.bluetooth.OobData;
import android.bluetooth.UidTraffic;
@@ -115,7 +102,6 @@ import android.os.Message;
import android.os.ParcelUuid;
import android.os.Parcelable;
import android.os.PowerManager;
-import android.os.Process;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.SystemClock;
@@ -125,13 +111,11 @@ import android.provider.DeviceConfig;
import android.provider.Settings;
import android.sysprop.BluetoothProperties;
import android.text.TextUtils;
-import android.util.Base64;
import android.util.Log;
import android.util.Pair;
import android.util.SparseArray;
import com.android.bluetooth.BluetoothEventLogger;
-import com.android.bluetooth.BluetoothMetricsProto;
import com.android.bluetooth.BluetoothStatsLog;
import com.android.bluetooth.R;
import com.android.bluetooth.Utils;
@@ -173,16 +157,10 @@ import com.android.bluetooth.telephony.BluetoothInCallService;
import com.android.bluetooth.vc.VolumeControlService;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.modules.expresslog.Counter;
import com.android.modules.utils.BackgroundThread;
import com.android.modules.utils.BytesMatcher;
-import libcore.util.SneakyThrow;
-
-import com.google.protobuf.InvalidProtocolBufferException;
-
import java.io.FileDescriptor;
-import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.file.FileVisitResult;
@@ -196,7 +174,6 @@ import java.time.Instant;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@@ -207,14 +184,12 @@ import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
-import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Executor;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.regex.Pattern;
-import java.util.stream.Collectors;
public class AdapterService extends Service {
private static final String TAG =
@@ -226,9 +201,6 @@ public class AdapterService extends Service {
private static final int MESSAGE_PREFERRED_AUDIO_PROFILES_AUDIO_FRAMEWORK_TIMEOUT = 4;
private static final int CONTROLLER_ENERGY_UPDATE_TIMEOUT_MILLIS = 100;
- private static final int MIN_ADVT_INSTANCES_FOR_MA = 5;
- private static final int MIN_OFFLOADED_FILTERS = 10;
- private static final int MIN_OFFLOADED_SCAN_STORAGE_BYTES = 1024;
private static final Duration PENDING_SOCKET_HANDOFF_TIMEOUT = Duration.ofMinutes(1);
private static final Duration GENERATE_LOCAL_OOB_DATA_TIMEOUT = Duration.ofSeconds(2);
@@ -310,7 +282,7 @@ public class AdapterService extends Service {
new ArrayList<>();
private BluetoothAdapter mAdapter;
- @VisibleForTesting AdapterProperties mAdapterProperties;
+ private AdapterProperties mAdapterProperties;
private AdapterState mAdapterStateMachine;
private BondStateMachine mBondStateMachine;
private RemoteDevices mRemoteDevices;
@@ -342,10 +314,10 @@ public class AdapterService extends Service {
private BluetoothSocketManagerBinder mBluetoothSocketManagerBinder;
private BluetoothKeystoreService mBluetoothKeystoreService;
- private A2dpService mA2dpService;
- private A2dpSinkService mA2dpSinkService;
private HeadsetService mHeadsetService;
private HeadsetClientService mHeadsetClientService;
+ private A2dpService mA2dpService;
+ private A2dpSinkService mA2dpSinkService;
private BluetoothMapService mMapService;
private MapClientService mMapClientService;
private HidDeviceService mHidDeviceService;
@@ -423,10 +395,6 @@ public class AdapterService extends Service {
return sAdapterService;
}
- AdapterNativeInterface getNative() {
- return mNativeInterface;
- }
-
/** Allow test to set an AdapterService to be return by AdapterService.getAdapterService() */
@VisibleForTesting
public static synchronized void setAdapterService(AdapterService instance) {
@@ -792,10 +760,76 @@ public class AdapterService extends Service {
return mActiveDeviceManager;
}
+ public RemoteDevices getRemoteDevices() {
+ return mRemoteDevices;
+ }
+
public SilenceDeviceManager getSilenceDeviceManager() {
return mSilenceDeviceManager;
}
+ AdapterNativeInterface getNative() {
+ return mNativeInterface;
+ }
+
+ AdapterServiceHandler getHandler() {
+ return mHandler;
+ }
+
+ DatabaseManager getDatabaseManager() {
+ return mDatabaseManager;
+ }
+
+ AdapterProperties getAdapterProperties() {
+ return mAdapterProperties;
+ }
+
+ Map<BluetoothDevice, RemoteCallbackList<IBluetoothMetadataListener>> getMetadataListeners() {
+ return mMetadataListeners;
+ }
+
+ Map<String, CallerInfo> getBondAttemptCallerInfo() {
+ return mBondAttemptCallerInfo;
+ }
+
+ Optional<PhonePolicy> getPhonePolicy() {
+ return mPhonePolicy;
+ }
+
+ BondStateMachine getBondStateMachine() {
+ return mBondStateMachine;
+ }
+
+ CompanionDeviceManager getCompanionDeviceManager() {
+ return mCompanionDeviceManager;
+ }
+
+ BluetoothSocketManagerBinder getBluetoothSocketManagerBinder() {
+ return mBluetoothSocketManagerBinder;
+ }
+
+ RemoteCallbackList<IBluetoothConnectionCallback> getBluetoothConnectionCallbacks() {
+ return mBluetoothConnectionCallbacks;
+ }
+
+ RemoteCallbackList<IBluetoothPreferredAudioProfilesCallback>
+ getPreferredAudioProfilesCallbacks() {
+ return mPreferredAudioProfilesCallbacks;
+ }
+
+ RemoteCallbackList<IBluetoothQualityReportReadyCallback>
+ getBluetoothQualityReportReadyCallbacks() {
+ return mBluetoothQualityReportReadyCallbacks;
+ }
+
+ BluetoothHciVendorSpecificDispatcher getBluetoothHciVendorSpecificDispatcher() {
+ return mBluetoothHciVendorSpecificDispatcher;
+ }
+
+ BluetoothHciVendorSpecificNativeInterface getBluetoothHciVendorSpecificNativeInterface() {
+ return mBluetoothHciVendorSpecificNativeInterface;
+ }
+
/**
* Log L2CAP CoC Server Connection Metrics
*
@@ -1728,14 +1762,6 @@ public class AdapterService extends Service {
* @return false if one of profile is enabled or disabled, true otherwise
*/
boolean isAllProfilesUnknown(BluetoothDevice device) {
- if (mA2dpService != null
- && mA2dpService.getConnectionPolicy(device) != CONNECTION_POLICY_UNKNOWN) {
- return false;
- }
- if (mA2dpSinkService != null
- && mA2dpSinkService.getConnectionPolicy(device) != CONNECTION_POLICY_UNKNOWN) {
- return false;
- }
if (mHeadsetService != null
&& mHeadsetService.getConnectionPolicy(device) != CONNECTION_POLICY_UNKNOWN) {
return false;
@@ -1744,6 +1770,14 @@ public class AdapterService extends Service {
&& mHeadsetClientService.getConnectionPolicy(device) != CONNECTION_POLICY_UNKNOWN) {
return false;
}
+ if (mA2dpService != null
+ && mA2dpService.getConnectionPolicy(device) != CONNECTION_POLICY_UNKNOWN) {
+ return false;
+ }
+ if (mA2dpSinkService != null
+ && mA2dpSinkService.getConnectionPolicy(device) != CONNECTION_POLICY_UNKNOWN) {
+ return false;
+ }
if (mMapClientService != null
&& mMapClientService.getConnectionPolicy(device) != CONNECTION_POLICY_UNKNOWN) {
return false;
@@ -1803,18 +1837,7 @@ public class AdapterService extends Service {
Log.i(TAG, "connectEnabledProfiles: Connecting Coordinated Set Profile");
mCsipSetCoordinatorService.connect(device);
}
- if (mA2dpService != null
- && isProfileSupported(device, BluetoothProfile.A2DP)
- && mA2dpService.getConnectionPolicy(device) > CONNECTION_POLICY_FORBIDDEN) {
- Log.i(TAG, "connectEnabledProfiles: Connecting A2dp");
- mA2dpService.connect(device);
- }
- if (mA2dpSinkService != null
- && isProfileSupported(device, BluetoothProfile.A2DP_SINK)
- && mA2dpSinkService.getConnectionPolicy(device) > CONNECTION_POLICY_FORBIDDEN) {
- Log.i(TAG, "connectEnabledProfiles: Connecting A2dp Sink");
- mA2dpSinkService.connect(device);
- }
+ // Order matters, some devices do not accept A2DP connection before HFP connection
if (mHeadsetService != null
&& isProfileSupported(device, BluetoothProfile.HEADSET)
&& mHeadsetService.getConnectionPolicy(device) > CONNECTION_POLICY_FORBIDDEN) {
@@ -1828,6 +1851,18 @@ public class AdapterService extends Service {
Log.i(TAG, "connectEnabledProfiles: Connecting HFP");
mHeadsetClientService.connect(device);
}
+ if (mA2dpService != null
+ && isProfileSupported(device, BluetoothProfile.A2DP)
+ && mA2dpService.getConnectionPolicy(device) > CONNECTION_POLICY_FORBIDDEN) {
+ Log.i(TAG, "connectEnabledProfiles: Connecting A2dp");
+ mA2dpService.connect(device);
+ }
+ if (mA2dpSinkService != null
+ && isProfileSupported(device, BluetoothProfile.A2DP_SINK)
+ && mA2dpSinkService.getConnectionPolicy(device) > CONNECTION_POLICY_FORBIDDEN) {
+ Log.i(TAG, "connectEnabledProfiles: Connecting A2dp Sink");
+ mA2dpSinkService.connect(device);
+ }
if (mMapClientService != null
&& isProfileSupported(device, BluetoothProfile.MAP_CLIENT)
&& mMapClientService.getConnectionPolicy(device) > CONNECTION_POLICY_FORBIDDEN) {
@@ -1910,10 +1945,10 @@ public class AdapterService extends Service {
/** Initializes all the profile services fields */
private void initProfileServices() {
Log.i(TAG, "initProfileServices: Initializing all bluetooth profile services");
- mA2dpService = A2dpService.getA2dpService();
- mA2dpSinkService = A2dpSinkService.getA2dpSinkService();
mHeadsetService = HeadsetService.getHeadsetService();
mHeadsetClientService = HeadsetClientService.getHeadsetClientService();
+ mA2dpService = A2dpService.getA2dpService();
+ mA2dpSinkService = A2dpSinkService.getA2dpSinkService();
mMapService = BluetoothMapService.getBluetoothMapService();
mMapClientService = MapClientService.getMapClientService();
mHidDeviceService = HidDeviceService.getHidDeviceService();
@@ -1933,7 +1968,7 @@ public class AdapterService extends Service {
@BluetoothAdapter.RfcommListenerResult
@RequiresPermission(BLUETOOTH_CONNECT)
- private int startRfcommListener(
+ int startRfcommListener(
String name, ParcelUuid uuid, PendingIntent pendingIntent, AttributionSource source) {
if (mBluetoothServerSockets.containsKey(uuid.getUuid())) {
Log.d(TAG, "Cannot start RFCOMM listener: UUID " + uuid.getUuid() + "already in use.");
@@ -1950,7 +1985,6 @@ public class AdapterService extends Service {
}
@BluetoothAdapter.RfcommListenerResult
- @VisibleForTesting
int stopRfcommListener(ParcelUuid uuid, AttributionSource source) {
RfcommListenerData listenerData = mBluetoothServerSockets.get(uuid.getUuid());
@@ -1969,7 +2003,6 @@ public class AdapterService extends Service {
return listenerData.closeServerAndPendingSockets(mHandler);
}
- @VisibleForTesting
IncomingRfcommSocketInfo retrievePendingSocketForServiceRecord(
ParcelUuid uuid, AttributionSource source) {
IncomingRfcommSocketInfo socketInfo = new IncomingRfcommSocketInfo();
@@ -2125,7 +2158,6 @@ public class AdapterService extends Service {
}
}
- @VisibleForTesting
boolean isAvailable() {
return !mCleaningUp;
}
@@ -2161,2203 +2193,6 @@ public class AdapterService extends Service {
}
/**
- * There is no leak of this binder since it is never re-used and the process is systematically
- * killed
- */
- @VisibleForTesting
- public static class AdapterServiceBinder extends IBluetooth.Stub {
- private final AdapterService mService;
-
- AdapterServiceBinder(AdapterService svc) {
- mService = svc;
- }
-
- public AdapterService getService() {
- if (!mService.isAvailable()) {
- return null;
- }
- return mService;
- }
-
- @Override
- public int getState() {
- AdapterService service = getService();
- if (service == null) {
- return BluetoothAdapter.STATE_OFF;
- }
-
- return service.getState();
- }
-
- @Override
- public void killBluetoothProcess() {
- mService.enforceCallingPermission(BLUETOOTH_PRIVILEGED, null);
-
- Runnable killAction =
- () -> {
- if (Flags.killInsteadOfExit()) {
- Log.i(TAG, "killBluetoothProcess: Calling killProcess(myPid())");
- Process.killProcess(Process.myPid());
- } else {
- Log.i(TAG, "killBluetoothProcess: Calling System.exit");
- System.exit(0);
- }
- };
-
- // Post on the main handler to let the cleanup complete before calling exit
- mService.mHandler.post(killAction);
-
- try {
- // Wait for Bluetooth to be killed from its main thread
- Thread.sleep(1_000); // SystemServer is waiting 2000 ms, we need to wait less here
- } catch (InterruptedException e) {
- Log.e(TAG, "killBluetoothProcess: Interrupted while waiting for kill");
- }
-
- // Bluetooth cannot be killed on the main thread; it is in a deadLock.
- // Trying to recover by killing the Bluetooth from the binder thread.
- // This is bad :(
- Counter.logIncrement("bluetooth.value_kill_from_binder_thread");
- Log.wtf(TAG, "Failed to kill Bluetooth using its main thread. Trying from binder");
- killAction.run();
- }
-
- @Override
- public void offToBleOn(boolean quietMode, AttributionSource source) {
- AdapterService service = getService();
- if (service == null
- || !callerIsSystemOrActiveOrManagedUser(service, TAG, "offToBleOn")) {
- return;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- service.offToBleOn(quietMode);
- }
-
- @Override
- public void onToBleOn(AttributionSource source) {
- AdapterService service = getService();
- if (service == null
- || !callerIsSystemOrActiveOrManagedUser(service, TAG, "onToBleOn")) {
- return;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- service.onToBleOn();
- }
-
- @Override
- public String getAddress(AttributionSource source) {
- AdapterService service = getService();
- if (service == null
- || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getAddress")
- || !Utils.checkConnectPermissionForDataDelivery(
- service, source, "AdapterService getAddress")) {
- return null;
- }
-
- service.enforceCallingOrSelfPermission(LOCAL_MAC_ADDRESS, null);
-
- return Utils.getAddressStringFromByte(service.mAdapterProperties.getAddress());
- }
-
- @Override
- public List<ParcelUuid> getUuids(AttributionSource source) {
- AdapterService service = getService();
- if (service == null
- || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getUuids")
- || !Utils.checkConnectPermissionForDataDelivery(
- service, source, "AdapterService getUuids")) {
- return Collections.emptyList();
- }
-
- ParcelUuid[] parcels = service.mAdapterProperties.getUuids();
- if (parcels == null) {
- parcels = new ParcelUuid[0];
- }
- return Arrays.asList(parcels);
- }
-
- @Override
- public String getIdentityAddress(String address) {
- AdapterService service = getService();
- if (service == null
- || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getIdentityAddress")
- || !Utils.checkConnectPermissionForDataDelivery(
- service,
- Utils.getCallingAttributionSource(mService),
- "AdapterService getIdentityAddress")) {
- return null;
- }
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- return service.getIdentityAddress(address);
- }
-
- @Override
- @NonNull
- public BluetoothAddress getIdentityAddressWithType(@NonNull String address) {
- AdapterService service = getService();
- if (service == null
- || !callerIsSystemOrActiveOrManagedUser(
- service, TAG, "getIdentityAddressWithType")
- || !Utils.checkConnectPermissionForDataDelivery(
- service,
- Utils.getCallingAttributionSource(mService),
- "AdapterService getIdentityAddressWithType")) {
- return new BluetoothAddress(null, BluetoothDevice.ADDRESS_TYPE_UNKNOWN);
- }
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- return service.getIdentityAddressWithType(address);
- }
-
- @Override
- public String getName(AttributionSource source) {
- AdapterService service = getService();
- if (service == null
- || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getName")
- || !Utils.checkConnectPermissionForDataDelivery(
- service, source, "AdapterService getName")) {
- return null;
- }
-
- return service.getName();
- }
-
- @Override
- public int getNameLengthForAdvertise(AttributionSource source) {
- AdapterService service = getService();
- if (service == null
- || !callerIsSystemOrActiveOrManagedUser(
- service, TAG, "getNameLengthForAdvertise")
- || !Utils.checkAdvertisePermissionForDataDelivery(service, source, TAG)) {
- return -1;
- }
-
- return service.getNameLengthForAdvertise();
- }
-
- @Override
- public boolean setName(String name, AttributionSource source) {
- AdapterService service = getService();
- if (service == null
- || !callerIsSystemOrActiveOrManagedUser(service, TAG, "setName")
- || !Utils.checkConnectPermissionForDataDelivery(
- service, source, "AdapterService setName")) {
- return false;
- }
-
- if (Flags.emptyNamesAreInvalid()) {
- requireNonNull(name);
- name = name.trim();
- if (name.isEmpty()) {
- throw new IllegalArgumentException("Empty names are not valid");
- }
- }
-
- Log.d(TAG, "AdapterServiceBinder.setName(" + name + ")");
- return service.mAdapterProperties.setName(name);
- }
-
- @Override
- public int getScanMode(AttributionSource source) {
- AdapterService service = getService();
- if (service == null
- || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getScanMode")
- || !Utils.checkScanPermissionForDataDelivery(
- service, source, "AdapterService getScanMode")) {
- return SCAN_MODE_NONE;
- }
-
- return service.getScanMode();
- }
-
- @Override
- public int setScanMode(int mode, AttributionSource source) {
- AdapterService service = getService();
- if (service == null
- || !callerIsSystemOrActiveOrManagedUser(service, TAG, "setScanMode")
- || !Utils.checkScanPermissionForDataDelivery(
- service, source, "AdapterService setScanMode")) {
- return BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_SCAN_PERMISSION;
- }
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- String logCaller = Utils.getUidPidString() + " packageName=" + source.getPackageName();
- CompletableFuture<Boolean> future = new CompletableFuture<>();
- mService.mHandler.post(
- () ->
- future.complete(
- service.getState() == BluetoothAdapter.STATE_ON
- && service.setScanMode(mode, logCaller)));
- return future.join()
- ? BluetoothStatusCodes.SUCCESS
- : BluetoothStatusCodes.ERROR_UNKNOWN;
- }
-
- @Override
- public long getDiscoverableTimeout(AttributionSource source) {
- AdapterService service = getService();
- if (service == null
- || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getDiscoverableTimeout")
- || !Utils.checkScanPermissionForDataDelivery(
- service, source, "AdapterService getDiscoverableTimeout")) {
- return -1;
- }
-
- return service.mAdapterProperties.getDiscoverableTimeout();
- }
-
- @Override
- public int setDiscoverableTimeout(long timeout, AttributionSource source) {
- AdapterService service = getService();
- if (service == null
- || !callerIsSystemOrActiveOrManagedUser(service, TAG, "setDiscoverableTimeout")
- || !Utils.checkScanPermissionForDataDelivery(
- service, source, "AdapterService setDiscoverableTimeout")) {
- return BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_SCAN_PERMISSION;
- }
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- return service.mAdapterProperties.setDiscoverableTimeout((int) timeout)
- ? BluetoothStatusCodes.SUCCESS
- : BluetoothStatusCodes.ERROR_UNKNOWN;
- }
-
- @Override
- public boolean startDiscovery(AttributionSource source) {
- AdapterService service = getService();
- if (service == null
- || !callerIsSystemOrActiveOrManagedUser(service, TAG, "startDiscovery")) {
- return false;
- }
-
- if (!Utils.checkScanPermissionForDataDelivery(service, source, "Starting discovery.")) {
- return false;
- }
-
- Log.i(TAG, "startDiscovery: from " + Utils.getUidPidString());
- return service.startDiscovery(source);
- }
-
- @Override
- public boolean cancelDiscovery(AttributionSource source) {
- AdapterService service = getService();
- if (service == null
- || !callerIsSystemOrActiveOrManagedUser(service, TAG, "cancelDiscovery")
- || !Utils.checkScanPermissionForDataDelivery(
- service, source, "AdapterService cancelDiscovery")) {
- return false;
- }
-
- Log.i(TAG, "cancelDiscovery: from " + Utils.getUidPidString());
- return service.mNativeInterface.cancelDiscovery();
- }
-
- @Override
- public boolean isDiscovering(AttributionSource source) {
- AdapterService service = getService();
- if (service == null
- || !callerIsSystemOrActiveOrManagedUser(service, TAG, "isDiscovering")
- || !Utils.checkScanPermissionForDataDelivery(
- service, source, "AdapterService isDiscovering")) {
- return false;
- }
-
- return service.mAdapterProperties.isDiscovering();
- }
-
- @Override
- public long getDiscoveryEndMillis(AttributionSource source) {
- AdapterService service = getService();
- if (service == null
- || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getDiscoveryEndMillis")
- || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
- return -1;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- return service.mAdapterProperties.discoveryEndMillis();
- }
-
- @Override
- public List<BluetoothDevice> getMostRecentlyConnectedDevices(AttributionSource source) {
- // don't check caller, may be called from system UI
- AdapterService service = getService();
- if (service == null
- || !Utils.checkConnectPermissionForDataDelivery(
- service, source, "AdapterService getMostRecentlyConnectedDevices")) {
- return Collections.emptyList();
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- return service.mDatabaseManager.getMostRecentlyConnectedDevices();
- }
-
- @Override
- public List<BluetoothDevice> getBondedDevices(AttributionSource source) {
- // don't check caller, may be called from system UI
- AdapterService service = getService();
- if (service == null
- || !Utils.checkConnectPermissionForDataDelivery(
- service, source, "AdapterService getBondedDevices")) {
- return Collections.emptyList();
- }
-
- return Arrays.asList(service.getBondedDevices());
- }
-
- @Override
- public int getAdapterConnectionState() {
- // don't check caller, may be called from system UI
- AdapterService service = getService();
- if (service == null) {
- return BluetoothAdapter.STATE_DISCONNECTED;
- }
-
- return service.mAdapterProperties.getConnectionState();
- }
-
- /**
- * This method has an associated binder cache. The invalidation methods must be changed if
- * the logic behind this method changes.
- */
- @Override
- public int getProfileConnectionState(int profile, AttributionSource source) {
- AdapterService service = getService();
- boolean checkConnect = false;
- final int callingUid = Binder.getCallingUid();
- final long token = Binder.clearCallingIdentity();
- try {
- checkConnect = CompatChanges.isChangeEnabled(ENFORCE_CONNECT, callingUid);
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- if (service == null
- || !callerIsSystemOrActiveOrManagedUser(
- service, TAG, "getProfileConnectionState")
- || (checkConnect
- && !Utils.checkConnectPermissionForDataDelivery(
- service, source, "AdapterService getProfileConnectionState"))) {
- return STATE_DISCONNECTED;
- }
-
- return service.mAdapterProperties.getProfileConnectionState(profile);
- }
-
- @Override
- public boolean createBond(
- BluetoothDevice device,
- int transport,
- OobData remoteP192Data,
- OobData remoteP256Data,
- AttributionSource source) {
- AdapterService service = getService();
- if (service == null
- || !callerIsSystemOrActiveOrManagedUser(service, TAG, "createBond")
- || !Utils.checkConnectPermissionForDataDelivery(
- service, source, "AdapterService createBond")) {
- return false;
- }
-
- // This conditional is required to satisfy permission dependencies
- // since createBond calls createBondOutOfBand with null value passed as data.
- // BluetoothDevice#createBond requires BLUETOOTH_ADMIN only.
- service.enforceBluetoothPrivilegedPermissionIfNeeded(remoteP192Data, remoteP256Data);
-
- Log.i(
- TAG,
- "createBond:"
- + (" device=" + device)
- + (" transport=" + transport)
- + (" from " + Utils.getUidPidString()));
- return service.createBond(
- device, transport, remoteP192Data, remoteP256Data, source.getPackageName());
- }
-
- @Override
- public boolean cancelBondProcess(BluetoothDevice device, AttributionSource source) {
- AdapterService service = getService();
- if (service == null
- || !callerIsSystemOrActiveOrManagedUser(service, TAG, "cancelBondProcess")
- || !Utils.checkConnectPermissionForDataDelivery(
- service, source, "AdapterService cancelBondProcess")) {
- return false;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- Log.i(TAG, "cancelBondProcess: device=" + device + ", from " + Utils.getUidPidString());
-
- DeviceProperties deviceProp = service.mRemoteDevices.getDeviceProperties(device);
- if (deviceProp != null) {
- deviceProp.setBondingInitiatedLocally(false);
- }
-
- service.logUserBondResponse(device, false, source);
- return service.mNativeInterface.cancelBond(getBytesFromAddress(device.getAddress()));
- }
-
- @Override
- public boolean removeBond(BluetoothDevice device, AttributionSource source) {
- AdapterService service = getService();
- if (service == null
- || !callerIsSystemOrActiveOrManagedUser(service, TAG, "removeBond")
- || !Utils.checkConnectPermissionForDataDelivery(
- service, source, "AdapterService removeBond")) {
- return false;
- }
-
- Log.i(TAG, "removeBond: device=" + device + ", from " + Utils.getUidPidString());
-
- DeviceProperties deviceProp = service.mRemoteDevices.getDeviceProperties(device);
- if (deviceProp == null || deviceProp.getBondState() != BluetoothDevice.BOND_BONDED) {
- Log.w(
- TAG,
- device
- + " cannot be removed since "
- + ((deviceProp == null)
- ? "properties are empty"
- : "bond state is " + deviceProp.getBondState()));
- return false;
- }
- service.logUserBondResponse(device, false, source);
- service.mBondAttemptCallerInfo.remove(device.getAddress());
- service.mPhonePolicy.ifPresent(policy -> policy.onRemoveBondRequest(device));
- deviceProp.setBondingInitiatedLocally(false);
-
- Message msg = service.mBondStateMachine.obtainMessage(BondStateMachine.REMOVE_BOND);
- msg.obj = device;
- service.mBondStateMachine.sendMessage(msg);
- return true;
- }
-
- @Override
- public int getBondState(BluetoothDevice device, AttributionSource source) {
- // don't check caller, may be called from system UI
- AdapterService service = getService();
- if (service == null
- || !Utils.checkConnectPermissionForDataDelivery(
- service, source, "AdapterService getBondState")) {
- return BluetoothDevice.BOND_NONE;
- }
-
- return service.getBondState(device);
- }
-
- @Override
- public boolean isBondingInitiatedLocally(BluetoothDevice device, AttributionSource source) {
- // don't check caller, may be called from system UI
- AdapterService service = getService();
- if (service == null
- || !Utils.checkConnectPermissionForDataDelivery(
- service, source, "AdapterService isBondingInitiatedLocally")) {
- return false;
- }
-
- DeviceProperties deviceProp = service.mRemoteDevices.getDeviceProperties(device);
- return deviceProp != null && deviceProp.isBondingInitiatedLocally();
- }
-
- @Override
- public void generateLocalOobData(
- int transport, IBluetoothOobDataCallback callback, AttributionSource source) {
- AdapterService service = getService();
- if (service == null
- || !callerIsSystemOrActiveOrManagedUser(service, TAG, "generateLocalOobData")
- || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
- return;
- }
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- service.generateLocalOobData(transport, callback);
- }
-
- @Override
- public long getSupportedProfiles(AttributionSource source) {
- AdapterService service = getService();
- if (service == null
- || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
- return 0;
- }
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- return Config.getSupportedProfilesBitMask();
- }
-
- @Override
- public int getConnectionState(BluetoothDevice device, AttributionSource source) {
- AdapterService service = getService();
- if (service == null
- || !Utils.checkConnectPermissionForDataDelivery(
- service, source, "AdapterService getConnectionState")) {
- return BluetoothDevice.CONNECTION_STATE_DISCONNECTED;
- }
-
- return service.getConnectionState(device);
- }
-
- @Override
- public int getConnectionHandle(
- BluetoothDevice device, int transport, AttributionSource source) {
- AdapterService service = getService();
- if (service == null
- || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getConnectionHandle")
- || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
- return BluetoothDevice.ERROR;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- return service.getConnectionHandle(device, transport);
- }
-
- @Override
- public boolean canBondWithoutDialog(BluetoothDevice device, AttributionSource source) {
- AdapterService service = getService();
- if (service == null
- || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
- return false;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- return service.canBondWithoutDialog(device);
- }
-
- @Override
- public String getPackageNameOfBondingApplication(
- BluetoothDevice device, AttributionSource source) {
- AdapterService service = getService();
-
- if (service == null
- || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
- return null;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- return service.getPackageNameOfBondingApplication(device);
- }
-
- @Override
- public boolean removeActiveDevice(@ActiveDeviceUse int profiles, AttributionSource source) {
- AdapterService service = getService();
- if (service == null
- || !callerIsSystemOrActiveOrManagedUser(service, TAG, "removeActiveDevice")
- || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
- return false;
- }
-
- service.enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, null);
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- Log.i(
- TAG,
- "removeActiveDevice: profiles="
- + profiles
- + ", from "
- + Utils.getUidPidString());
- return service.setActiveDevice(null, profiles);
- }
-
- @Override
- public boolean setActiveDevice(
- BluetoothDevice device, @ActiveDeviceUse int profiles, AttributionSource source) {
- AdapterService service = getService();
- if (service == null
- || !callerIsSystemOrActiveOrManagedUser(service, TAG, "setActiveDevice")
- || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
- return false;
- }
-
- service.enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, null);
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- Log.i(
- TAG,
- "setActiveDevice: device="
- + device
- + ", profiles="
- + profiles
- + ", from "
- + Utils.getUidPidString());
-
- return service.setActiveDevice(device, profiles);
- }
-
- @Override
- public List<BluetoothDevice> getActiveDevices(
- @ActiveDeviceProfile int profile, AttributionSource source) {
- AdapterService service = getService();
- if (service == null
- || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getActiveDevices")
- || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
- return Collections.emptyList();
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- return service.getActiveDevices(profile);
- }
-
- @Override
- public int connectAllEnabledProfiles(BluetoothDevice device, AttributionSource source) {
- AdapterService service = getService();
- if (service == null || !service.isEnabled()) {
- return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED;
- }
- if (!callerIsSystemOrActiveOrManagedUser(service, TAG, "connectAllEnabledProfiles")) {
- return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ALLOWED;
- }
- if (device == null) {
- throw new IllegalArgumentException("device cannot be null");
- }
- if (!BluetoothAdapter.checkBluetoothAddress(device.getAddress())) {
- throw new IllegalArgumentException("device cannot have an invalid address");
- }
- if (!Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
- return BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION;
- }
-
- service.enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, null);
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- Log.i(
- TAG,
- "connectAllEnabledProfiles: device="
- + device
- + ", from "
- + Utils.getUidPidString());
- MetricsLogger.getInstance()
- .logBluetoothEvent(
- device,
- BluetoothStatsLog
- .BLUETOOTH_CROSS_LAYER_EVENT_REPORTED__EVENT_TYPE__INITIATOR_CONNECTION,
- BluetoothStatsLog.BLUETOOTH_CROSS_LAYER_EVENT_REPORTED__STATE__START,
- source.getUid());
-
- try {
- return service.connectAllEnabledProfiles(device);
- } catch (Exception e) {
- Log.v(TAG, "connectAllEnabledProfiles() failed", e);
- SneakyThrow.sneakyThrow(e);
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public int disconnectAllEnabledProfiles(BluetoothDevice device, AttributionSource source) {
- AdapterService service = getService();
- if (service == null) {
- return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED;
- }
- if (!callerIsSystemOrActiveOrManagedUser(
- service, TAG, "disconnectAllEnabledProfiles")) {
- return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ALLOWED;
- }
- if (device == null) {
- throw new IllegalArgumentException("device cannot be null");
- }
- if (!BluetoothAdapter.checkBluetoothAddress(device.getAddress())) {
- throw new IllegalArgumentException("device cannot have an invalid address");
- }
- if (!Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
- return BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- Log.i(
- TAG,
- "disconnectAllEnabledProfiles: device="
- + device
- + ", from "
- + Utils.getUidPidString());
-
- try {
- return service.disconnectAllEnabledProfiles(device);
- } catch (Exception e) {
- Log.v(TAG, "disconnectAllEnabledProfiles() failed", e);
- SneakyThrow.sneakyThrow(e);
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public String getRemoteName(BluetoothDevice device, AttributionSource source) {
- AdapterService service = getService();
- if (service == null
- || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getRemoteName")
- || !Utils.checkConnectPermissionForDataDelivery(
- service, source, "AdapterService getRemoteName")) {
- return null;
- }
-
- return service.getRemoteName(device);
- }
-
- @Override
- public int getRemoteType(BluetoothDevice device, AttributionSource source) {
- AdapterService service = getService();
- if (service == null
- || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getRemoteType")
- || !Utils.checkConnectPermissionForDataDelivery(
- service, source, "AdapterService getRemoteType")) {
- return BluetoothDevice.DEVICE_TYPE_UNKNOWN;
- }
-
- return service.getRemoteType(device);
- }
-
- @Override
- public String getRemoteAlias(BluetoothDevice device, AttributionSource source) {
- AdapterService service = getService();
- if (service == null
- || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getRemoteAlias")
- || !Utils.checkConnectPermissionForDataDelivery(
- service, source, "AdapterService getRemoteAlias")) {
- return null;
- }
-
- DeviceProperties deviceProp = service.mRemoteDevices.getDeviceProperties(device);
- return deviceProp != null ? deviceProp.getAlias() : null;
- }
-
- @Override
- public int setRemoteAlias(BluetoothDevice device, String name, AttributionSource source) {
- AdapterService service = getService();
- if (service == null) {
- return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED;
- }
- if (!callerIsSystemOrActiveOrManagedUser(service, TAG, "setRemoteAlias")) {
- return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ALLOWED;
- }
- if (name != null && name.isEmpty()) {
- throw new IllegalArgumentException("alias cannot be the empty string");
- }
-
- if (!Utils.checkConnectPermissionForDataDelivery(
- service, source, "AdapterService setRemoteAlias")) {
- return BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION;
- }
-
- Utils.enforceCdmAssociationIfNotBluetoothPrivileged(
- service, service.mCompanionDeviceManager, source, device);
-
- DeviceProperties deviceProp = service.mRemoteDevices.getDeviceProperties(device);
- if (deviceProp == null) {
- return BluetoothStatusCodes.ERROR_DEVICE_NOT_BONDED;
- }
- deviceProp.setAlias(device, name);
- return BluetoothStatusCodes.SUCCESS;
- }
-
- @Override
- public int getRemoteClass(BluetoothDevice device, AttributionSource source) {
- AdapterService service = getService();
- if (service == null
- || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getRemoteClass")
- || !Utils.checkConnectPermissionForDataDelivery(
- service, source, "AdapterService getRemoteClass")) {
- return 0;
- }
-
- return service.getRemoteClass(device);
- }
-
- @Override
- public List<ParcelUuid> getRemoteUuids(BluetoothDevice device, AttributionSource source) {
- AdapterService service = getService();
- if (service == null
- || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getRemoteUuids")
- || !Utils.checkConnectPermissionForDataDelivery(
- service, source, "AdapterService getRemoteUuids")) {
- return Collections.emptyList();
- }
-
- final ParcelUuid[] parcels = service.getRemoteUuids(device);
- if (parcels == null) {
- return null;
- }
- return Arrays.asList(parcels);
- }
-
- @Override
- public boolean fetchRemoteUuids(
- BluetoothDevice device, int transport, AttributionSource source) {
- AdapterService service = getService();
- if (service == null
- || !callerIsSystemOrActiveOrManagedUser(service, TAG, "fetchRemoteUuids")
- || !Utils.checkConnectPermissionForDataDelivery(
- service, source, "AdapterService fetchRemoteUuids")) {
- return false;
- }
- if (transport != TRANSPORT_AUTO) {
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- }
-
- Log.i(
- TAG,
- "fetchRemoteUuids: device="
- + device
- + ", transport="
- + transport
- + ", from "
- + Utils.getUidPidString());
-
- service.mRemoteDevices.fetchUuids(device, transport);
- MetricsLogger.getInstance().cacheCount(BluetoothProtoEnums.SDP_FETCH_UUID_REQUEST, 1);
- return true;
- }
-
- @Override
- public boolean setPin(
- BluetoothDevice device,
- boolean accept,
- int len,
- byte[] pinCode,
- AttributionSource source) {
- AdapterService service = getService();
- if (service == null
- || !callerIsSystemOrActiveOrManagedUser(service, TAG, "setPin")
- || !Utils.checkConnectPermissionForDataDelivery(
- service, source, "AdapterService setPin")) {
- return false;
- }
-
- DeviceProperties deviceProp = service.mRemoteDevices.getDeviceProperties(device);
- // Only allow setting a pin in bonding state, or bonded state in case of security
- // upgrade.
- if (deviceProp == null || !deviceProp.isBondingOrBonded()) {
- Log.e(TAG, "setPin: device=" + device + ", not bonding");
- return false;
- }
- if (pinCode.length != len) {
- android.util.EventLog.writeEvent(
- 0x534e4554, "139287605", -1, "PIN code length mismatch");
- return false;
- }
- service.logUserBondResponse(device, accept, source);
- Log.i(
- TAG,
- "setPin: device="
- + device
- + ", accept="
- + accept
- + ", from "
- + Utils.getUidPidString());
- return service.mNativeInterface.pinReply(
- getBytesFromAddress(device.getAddress()), accept, len, pinCode);
- }
-
- @Override
- public boolean setPasskey(
- BluetoothDevice device,
- boolean accept,
- int len,
- byte[] passkey,
- AttributionSource source) {
- AdapterService service = getService();
- if (service == null
- || !callerIsSystemOrActiveOrManagedUser(service, TAG, "setPasskey")
- || !Utils.checkConnectPermissionForDataDelivery(
- service, source, "AdapterService setPasskey")) {
- return false;
- }
-
- DeviceProperties deviceProp = service.mRemoteDevices.getDeviceProperties(device);
- if (deviceProp == null || !deviceProp.isBonding()) {
- Log.e(TAG, "setPasskey: device=" + device + ", not bonding");
- return false;
- }
- if (passkey.length != len) {
- android.util.EventLog.writeEvent(
- 0x534e4554, "139287605", -1, "Passkey length mismatch");
- return false;
- }
- service.logUserBondResponse(device, accept, source);
- Log.i(
- TAG,
- "setPasskey: device="
- + device
- + ", accept="
- + accept
- + ", from "
- + Utils.getUidPidString());
-
- return service.mNativeInterface.sspReply(
- getBytesFromAddress(device.getAddress()),
- AbstractionLayer.BT_SSP_VARIANT_PASSKEY_ENTRY,
- accept,
- Utils.byteArrayToInt(passkey));
- }
-
- @Override
- public boolean setPairingConfirmation(
- BluetoothDevice device, boolean accept, AttributionSource source) {
- AdapterService service = getService();
- if (service == null
- || !callerIsSystemOrActiveOrManagedUser(service, TAG, "setPairingConfirmation")
- || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
- return false;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- DeviceProperties deviceProp = service.mRemoteDevices.getDeviceProperties(device);
- if (deviceProp == null || !deviceProp.isBonding()) {
- Log.e(TAG, "setPairingConfirmation: device=" + device + ", not bonding");
- return false;
- }
- service.logUserBondResponse(device, accept, source);
- Log.i(
- TAG,
- "setPairingConfirmation: device="
- + device
- + ", accept="
- + accept
- + ", from "
- + Utils.getUidPidString());
-
- return service.mNativeInterface.sspReply(
- getBytesFromAddress(device.getAddress()),
- AbstractionLayer.BT_SSP_VARIANT_PASSKEY_CONFIRMATION,
- accept,
- 0);
- }
-
- @Override
- public boolean getSilenceMode(BluetoothDevice device, AttributionSource source) {
- AdapterService service = getService();
- if (service == null
- || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getSilenceMode")
- || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
- return false;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- return service.mSilenceDeviceManager.getSilenceMode(device);
- }
-
- @Override
- public boolean setSilenceMode(
- BluetoothDevice device, boolean silence, AttributionSource source) {
- AdapterService service = getService();
- if (service == null
- || !callerIsSystemOrActiveOrManagedUser(service, TAG, "setSilenceMode")
- || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
- return false;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- service.mSilenceDeviceManager.setSilenceMode(device, silence);
- return true;
- }
-
- @Override
- public int getPhonebookAccessPermission(BluetoothDevice device, AttributionSource source) {
- AdapterService service = getService();
- if (service == null
- || !callerIsSystemOrActiveOrManagedUser(
- service, TAG, "getPhonebookAccessPermission")
- || !Utils.checkConnectPermissionForDataDelivery(
- service, source, "AdapterService getPhonebookAccessPermission")) {
- return BluetoothDevice.ACCESS_UNKNOWN;
- }
-
- return service.getPhonebookAccessPermission(device);
- }
-
- @Override
- public boolean setPhonebookAccessPermission(
- BluetoothDevice device, int value, AttributionSource source) {
- AdapterService service = getService();
- if (service == null
- || !callerIsSystemOrActiveOrManagedUser(
- service, TAG, "setPhonebookAccessPermission")
- || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
- return false;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- service.setPhonebookAccessPermission(device, value);
- return true;
- }
-
- @Override
- public int getMessageAccessPermission(BluetoothDevice device, AttributionSource source) {
- AdapterService service = getService();
- if (service == null
- || !callerIsSystemOrActiveOrManagedUser(
- service, TAG, "getMessageAccessPermission")
- || !Utils.checkConnectPermissionForDataDelivery(
- service, source, "AdapterService getMessageAccessPermission")) {
- return BluetoothDevice.ACCESS_UNKNOWN;
- }
-
- return service.getMessageAccessPermission(device);
- }
-
- @Override
- public boolean setMessageAccessPermission(
- BluetoothDevice device, int value, AttributionSource source) {
- AdapterService service = getService();
- if (service == null
- || !callerIsSystemOrActiveOrManagedUser(
- service, TAG, "setMessageAccessPermission")
- || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
- return false;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- service.setMessageAccessPermission(device, value);
- return true;
- }
-
- @Override
- public int getSimAccessPermission(BluetoothDevice device, AttributionSource source) {
- AdapterService service = getService();
- if (service == null
- || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getSimAccessPermission")
- || !Utils.checkConnectPermissionForDataDelivery(
- service, source, "AdapterService getSimAccessPermission")) {
- return BluetoothDevice.ACCESS_UNKNOWN;
- }
-
- return service.getSimAccessPermission(device);
- }
-
- @Override
- public boolean setSimAccessPermission(
- BluetoothDevice device, int value, AttributionSource source) {
- AdapterService service = getService();
- if (service == null
- || !callerIsSystemOrActiveOrManagedUser(service, TAG, "setSimAccessPermission")
- || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
- return false;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- service.setSimAccessPermission(device, value);
- return true;
- }
-
- @Override
- public void logL2capcocServerConnection(
- BluetoothDevice device,
- int port,
- boolean isSecured,
- int result,
- long socketCreationTimeMillis,
- long socketCreationLatencyMillis,
- long socketConnectionTimeMillis,
- long timeoutMillis) {
- AdapterService service = getService();
- if (service == null) {
- return;
- }
- service.logL2capcocServerConnection(
- device,
- port,
- isSecured,
- result,
- socketCreationTimeMillis,
- socketCreationLatencyMillis,
- socketConnectionTimeMillis,
- timeoutMillis,
- Binder.getCallingUid());
- }
-
- @Override
- public IBluetoothSocketManager getSocketManager() {
- AdapterService service = getService();
- if (service == null) {
- return null;
- }
-
- return IBluetoothSocketManager.Stub.asInterface(service.mBluetoothSocketManagerBinder);
- }
-
- @Override
- public void logL2capcocClientConnection(
- BluetoothDevice device,
- int port,
- boolean isSecured,
- int result,
- long socketCreationTimeNanos,
- long socketCreationLatencyNanos,
- long socketConnectionTimeNanos) {
- AdapterService service = getService();
- if (service == null) {
- return;
- }
- service.logL2capcocClientConnection(
- device,
- port,
- isSecured,
- result,
- socketCreationTimeNanos,
- socketCreationLatencyNanos,
- socketConnectionTimeNanos,
- Binder.getCallingUid());
- }
-
- @Override
- public void logRfcommConnectionAttempt(
- BluetoothDevice device,
- boolean isSecured,
- int resultCode,
- long socketCreationTimeNanos,
- boolean isSerialPort) {
- AdapterService service = getService();
- if (service == null) {
- return;
- }
- service.logRfcommConnectionAttempt(
- device,
- isSecured,
- resultCode,
- socketCreationTimeNanos,
- isSerialPort,
- Binder.getCallingUid());
- }
-
- @Override
- public boolean sdpSearch(
- BluetoothDevice device, ParcelUuid uuid, AttributionSource source) {
- AdapterService service = getService();
- if (service == null
- || !callerIsSystemOrActiveOrManagedUser(service, TAG, "sdpSearch")
- || !Utils.checkConnectPermissionForDataDelivery(
- service, source, "AdapterService sdpSearch")) {
- return false;
- }
- return service.sdpSearch(device, uuid);
- }
-
- @Override
- public int getBatteryLevel(BluetoothDevice device, AttributionSource source) {
- AdapterService service = getService();
- if (service == null
- || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getBatteryLevel")
- || !Utils.checkConnectPermissionForDataDelivery(
- service, source, "AdapterService getBatteryLevel")) {
- return BluetoothDevice.BATTERY_LEVEL_UNKNOWN;
- }
-
- DeviceProperties deviceProp = service.mRemoteDevices.getDeviceProperties(device);
- if (deviceProp == null) {
- return BluetoothDevice.BATTERY_LEVEL_UNKNOWN;
- }
- return deviceProp.getBatteryLevel();
- }
-
- @Override
- public int getMaxConnectedAudioDevices(AttributionSource source) {
- // don't check caller, may be called from system UI
- AdapterService service = getService();
- if (service == null
- || !Utils.checkConnectPermissionForDataDelivery(
- service, source, "AdapterService getMaxConnectedAudioDevices")) {
- return -1;
- }
-
- return service.getMaxConnectedAudioDevices();
- }
-
- @Override
- public boolean factoryReset(AttributionSource source) {
- AdapterService service = getService();
- if (service == null
- || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
- return false;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- return service.factoryReset();
- }
-
- @Override
- public void registerBluetoothConnectionCallback(
- IBluetoothConnectionCallback callback, AttributionSource source) {
- AdapterService service = getService();
- if (service == null
- || !callerIsSystemOrActiveOrManagedUser(
- service, TAG, "registerBluetoothConnectionCallback")
- || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
- return;
- }
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- service.mBluetoothConnectionCallbacks.register(callback);
- }
-
- @Override
- public void unregisterBluetoothConnectionCallback(
- IBluetoothConnectionCallback callback, AttributionSource source) {
- AdapterService service = getService();
- if (service == null
- || !callerIsSystemOrActiveOrManagedUser(
- service, TAG, "unregisterBluetoothConnectionCallback")
- || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
- return;
- }
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- service.mBluetoothConnectionCallbacks.unregister(callback);
- }
-
- @Override
- public void registerCallback(IBluetoothCallback callback, AttributionSource source) {
- AdapterService service = getService();
- if (service == null
- || !callerIsSystemOrActiveOrManagedUser(service, TAG, "registerCallback")
- || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
- return;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- service.registerRemoteCallback(callback);
- }
-
- @Override
- public void unregisterCallback(IBluetoothCallback callback, AttributionSource source) {
- AdapterService service = getService();
- if (service == null
- || !callerIsSystemOrActiveOrManagedUser(service, TAG, "unregisterCallback")
- || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
- return;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- service.unregisterRemoteCallback(callback);
- }
-
- @Override
- public boolean isMultiAdvertisementSupported() {
- AdapterService service = getService();
- if (service == null) {
- return false;
- }
-
- int val = service.mAdapterProperties.getNumOfAdvertisementInstancesSupported();
- return val >= MIN_ADVT_INSTANCES_FOR_MA;
- }
-
- /**
- * This method has an associated binder cache. The invalidation methods must be changed if
- * the logic behind this method changes.
- */
- @Override
- public boolean isOffloadedFilteringSupported() {
- AdapterService service = getService();
- if (service == null) {
- return false;
- }
-
- int val = service.getNumOfOffloadedScanFilterSupported();
- return val >= MIN_OFFLOADED_FILTERS;
- }
-
- @Override
- public boolean isOffloadedScanBatchingSupported() {
- AdapterService service = getService();
- if (service == null) {
- return false;
- }
-
- int val = service.getOffloadedScanResultStorage();
- return val >= MIN_OFFLOADED_SCAN_STORAGE_BYTES;
- }
-
- @Override
- public boolean isLe2MPhySupported() {
- AdapterService service = getService();
- if (service == null) {
- return false;
- }
-
- return service.isLe2MPhySupported();
- }
-
- @Override
- public boolean isLeCodedPhySupported() {
- AdapterService service = getService();
- if (service == null) {
- return false;
- }
-
- return service.isLeCodedPhySupported();
- }
-
- @Override
- public boolean isLeExtendedAdvertisingSupported() {
- AdapterService service = getService();
- if (service == null) {
- return false;
- }
-
- return service.isLeExtendedAdvertisingSupported();
- }
-
- @Override
- public boolean isLePeriodicAdvertisingSupported() {
- AdapterService service = getService();
- if (service == null) {
- return false;
- }
-
- return service.isLePeriodicAdvertisingSupported();
- }
-
- @Override
- public int isLeAudioSupported() {
- AdapterService service = getService();
- if (service == null) {
- return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED;
- }
-
- Set<Integer> supportedProfileServices =
- Arrays.stream(Config.getSupportedProfiles())
- .boxed()
- .collect(Collectors.toSet());
- int[] leAudioUnicastProfiles = Config.getLeAudioUnicastProfiles();
-
- if (Arrays.stream(leAudioUnicastProfiles)
- .allMatch(supportedProfileServices::contains)) {
- return BluetoothStatusCodes.FEATURE_SUPPORTED;
- }
-
- return BluetoothStatusCodes.FEATURE_NOT_SUPPORTED;
- }
-
- @Override
- public int isLeAudioBroadcastSourceSupported() {
- AdapterService service = getService();
- if (service == null) {
- return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED;
- }
-
- long supportBitMask = Config.getSupportedProfilesBitMask();
- if ((supportBitMask & (1 << BluetoothProfile.LE_AUDIO_BROADCAST)) != 0) {
- return BluetoothStatusCodes.FEATURE_SUPPORTED;
- }
-
- return BluetoothStatusCodes.FEATURE_NOT_SUPPORTED;
- }
-
- @Override
- public int isLeAudioBroadcastAssistantSupported() {
- AdapterService service = getService();
- if (service == null) {
- return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED;
- }
-
- int[] supportedProfileServices = Config.getSupportedProfiles();
-
- if (Arrays.stream(supportedProfileServices)
- .anyMatch(
- profileId ->
- profileId == BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT)) {
- return BluetoothStatusCodes.FEATURE_SUPPORTED;
- }
-
- return BluetoothStatusCodes.FEATURE_NOT_SUPPORTED;
- }
-
- @Override
- public int isDistanceMeasurementSupported(AttributionSource source) {
- AdapterService service = getService();
- if (service == null) {
- return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED;
- } else if (!callerIsSystemOrActiveOrManagedUser(
- service, TAG, "isDistanceMeasurementSupported")) {
- return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ALLOWED;
- } else if (!Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
- return BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION;
- }
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- return BluetoothStatusCodes.FEATURE_SUPPORTED;
- }
-
- @Override
- public int getLeMaximumAdvertisingDataLength() {
- AdapterService service = getService();
- if (service == null) {
- return 0;
- }
-
- return service.getLeMaximumAdvertisingDataLength();
- }
-
- @Override
- public boolean isActivityAndEnergyReportingSupported() {
- AdapterService service = getService();
- if (service == null) {
- return false;
- }
-
- return service.mAdapterProperties.isActivityAndEnergyReportingSupported();
- }
-
- @Override
- public BluetoothActivityEnergyInfo reportActivityInfo(AttributionSource source) {
- AdapterService service = getService();
- if (service == null
- || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
- return null;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- return service.reportActivityInfo();
- }
-
- @Override
- public boolean registerMetadataListener(
- IBluetoothMetadataListener listener,
- BluetoothDevice device,
- AttributionSource source) {
- requireNonNull(device);
- requireNonNull(listener);
- AdapterService service = getService();
- if (service == null
- || !callerIsSystemOrActiveOrManagedUser(
- service, TAG, "registerMetadataListener")
- || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
- return false;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- service.mHandler.post(
- () ->
- service.mMetadataListeners
- .computeIfAbsent(device, k -> new RemoteCallbackList())
- .register(listener));
-
- return true;
- }
-
- @Override
- public boolean unregisterMetadataListener(
- IBluetoothMetadataListener listener,
- BluetoothDevice device,
- AttributionSource source) {
- requireNonNull(device);
- requireNonNull(listener);
- AdapterService service = getService();
- if (service == null
- || !callerIsSystemOrActiveOrManagedUser(
- service, TAG, "unregisterMetadataListener")
- || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
- return false;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- service.mHandler.post(
- () ->
- service.mMetadataListeners.computeIfPresent(
- device,
- (k, v) -> {
- v.unregister(listener);
- if (v.getRegisteredCallbackCount() == 0) {
- return null;
- }
- return v;
- }));
- return true;
- }
-
- @Override
- public boolean setMetadata(
- BluetoothDevice device, int key, byte[] value, AttributionSource source) {
- AdapterService service = getService();
- if (service == null
- || !callerIsSystemOrActiveOrManagedUser(service, TAG, "setMetadata")
- || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
- return false;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- return service.setMetadata(device, key, value);
- }
-
- @Override
- public byte[] getMetadata(BluetoothDevice device, int key, AttributionSource source) {
- AdapterService service = getService();
- if (service == null
- || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getMetadata")
- || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
- return null;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- return service.getMetadata(device, key);
- }
-
- @Override
- public int isRequestAudioPolicyAsSinkSupported(
- BluetoothDevice device, AttributionSource source) {
- AdapterService service = getService();
- if (service == null
- || !callerIsSystemOrActiveOrManagedUser(
- service, TAG, "isRequestAudioPolicyAsSinkSupported")
- || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
- return BluetoothStatusCodes.FEATURE_NOT_CONFIGURED;
- }
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- return service.isRequestAudioPolicyAsSinkSupported(device);
- }
-
- @Override
- public int requestAudioPolicyAsSink(
- BluetoothDevice device,
- BluetoothSinkAudioPolicy policies,
- AttributionSource source) {
- AdapterService service = getService();
- if (service == null) {
- return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED;
- } else if (!callerIsSystemOrActiveOrManagedUser(
- service, TAG, "requestAudioPolicyAsSink")) {
- return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ALLOWED;
- } else if (!Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
- return BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION;
- }
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- return service.requestAudioPolicyAsSink(device, policies);
- }
-
- @Override
- public BluetoothSinkAudioPolicy getRequestedAudioPolicyAsSink(
- BluetoothDevice device, AttributionSource source) {
- AdapterService service = getService();
- if (service == null
- || !callerIsSystemOrActiveOrManagedUser(
- service, TAG, "getRequestedAudioPolicyAsSink")
- || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
- return null;
- }
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- return service.getRequestedAudioPolicyAsSink(device);
- }
-
- @Override
- public void requestActivityInfo(
- IBluetoothActivityEnergyInfoListener listener, AttributionSource source) {
- BluetoothActivityEnergyInfo info = reportActivityInfo(source);
- try {
- listener.onBluetoothActivityEnergyInfoAvailable(info);
- } catch (RemoteException e) {
- Log.e(TAG, "onBluetoothActivityEnergyInfo: RemoteException", e);
- }
- }
-
- @Override
- public void bleOnToOn(AttributionSource source) {
- AdapterService service = getService();
- if (service == null
- || !callerIsSystemOrActiveOrManagedUser(service, TAG, "bleOnToOn")) {
- return;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- service.bleOnToOn();
- }
-
- @Override
- public void bleOnToOff(AttributionSource source) {
- AdapterService service = getService();
- if (service == null
- || !callerIsSystemOrActiveOrManagedUser(service, TAG, "bleOnToOff")) {
- return;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- service.bleOnToOff();
- }
-
- @Override
- public void dump(FileDescriptor fd, String[] args) {
- PrintWriter writer = new PrintWriter(new FileOutputStream(fd));
- AdapterService service = getService();
- if (service == null) {
- return;
- }
-
- service.enforceCallingOrSelfPermission(DUMP, null);
-
- service.dump(fd, writer, args);
- writer.close();
- }
-
- @Override
- public boolean allowLowLatencyAudio(boolean allowed, BluetoothDevice device) {
- AdapterService service = getService();
- if (service == null
- || !callerIsSystemOrActiveOrManagedUser(service, TAG, "allowLowLatencyAudio")
- || !Utils.checkConnectPermissionForDataDelivery(
- service,
- Utils.getCallingAttributionSource(service),
- "AdapterService allowLowLatencyAudio")) {
- return false;
- }
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- return service.allowLowLatencyAudio(allowed, device);
- }
-
- @Override
- public int startRfcommListener(
- String name,
- ParcelUuid uuid,
- PendingIntent pendingIntent,
- AttributionSource source) {
- AdapterService service = getService();
- if (service == null
- || !callerIsSystemOrActiveOrManagedUser(service, TAG, "startRfcommListener")
- || !Utils.checkConnectPermissionForDataDelivery(
- service, source, "AdapterService startRfcommListener")) {
- return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ALLOWED;
- }
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- return service.startRfcommListener(name, uuid, pendingIntent, source);
- }
-
- @Override
- public int stopRfcommListener(ParcelUuid uuid, AttributionSource source) {
- AdapterService service = getService();
- if (service == null
- || !callerIsSystemOrActiveOrManagedUser(service, TAG, "stopRfcommListener")
- || !Utils.checkConnectPermissionForDataDelivery(
- service, source, "AdapterService stopRfcommListener")) {
- return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ALLOWED;
- }
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- return service.stopRfcommListener(uuid, source);
- }
-
- @Override
- public IncomingRfcommSocketInfo retrievePendingSocketForServiceRecord(
- ParcelUuid uuid, AttributionSource source) {
- AdapterService service = getService();
- if (service == null
- || !callerIsSystemOrActiveOrManagedUser(
- service, TAG, "retrievePendingSocketForServiceRecord")
- || !Utils.checkConnectPermissionForDataDelivery(
- service,
- source,
- "AdapterService retrievePendingSocketForServiceRecord")) {
- return null;
- }
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- return service.retrievePendingSocketForServiceRecord(uuid, source);
- }
-
- @Override
- public void setForegroundUserId(int userId, AttributionSource source) {
- AdapterService service = getService();
- if (service == null
- || !Utils.checkConnectPermissionForDataDelivery(
- service,
- Utils.getCallingAttributionSource(mService),
- "AdapterService setForegroundUserId")) {
- return;
- }
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- Utils.setForegroundUserId(userId);
- }
-
- @Override
- public int setPreferredAudioProfiles(
- BluetoothDevice device, Bundle modeToProfileBundle, AttributionSource source) {
- AdapterService service = getService();
- if (service == null) {
- return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED;
- }
- if (!callerIsSystemOrActiveOrManagedUser(service, TAG, "setPreferredAudioProfiles")) {
- return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ALLOWED;
- }
- requireNonNull(device);
- requireNonNull(modeToProfileBundle);
- if (!BluetoothAdapter.checkBluetoothAddress(device.getAddress())) {
- throw new IllegalArgumentException("device cannot have an invalid address");
- }
- if (service.getBondState(device) != BluetoothDevice.BOND_BONDED) {
- return BluetoothStatusCodes.ERROR_DEVICE_NOT_BONDED;
- }
- if (!Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
- return BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION;
- }
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- return service.setPreferredAudioProfiles(device, modeToProfileBundle);
- }
-
- @Override
- public Bundle getPreferredAudioProfiles(BluetoothDevice device, AttributionSource source) {
- AdapterService service = getService();
- if (service == null) {
- return Bundle.EMPTY;
- }
- if (!callerIsSystemOrActiveOrManagedUser(service, TAG, "getPreferredAudioProfiles")) {
- return Bundle.EMPTY;
- }
- requireNonNull(device);
- if (!BluetoothAdapter.checkBluetoothAddress(device.getAddress())) {
- throw new IllegalArgumentException("device cannot have an invalid address");
- }
- if (service.getBondState(device) != BluetoothDevice.BOND_BONDED) {
- return Bundle.EMPTY;
- }
- if (!Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
- return Bundle.EMPTY;
- }
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- return service.getPreferredAudioProfiles(device);
- }
-
- @Override
- public int notifyActiveDeviceChangeApplied(
- BluetoothDevice device, AttributionSource source) {
- AdapterService service = getService();
- if (service == null) {
- return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED;
- }
- if (!callerIsSystem(TAG, "notifyActiveDeviceChangeApplied")) {
- return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ALLOWED;
- }
- requireNonNull(device);
- if (!BluetoothAdapter.checkBluetoothAddress(device.getAddress())) {
- throw new IllegalArgumentException("device cannot have an invalid address");
- }
- if (service.getBondState(device) != BluetoothDevice.BOND_BONDED) {
- return BluetoothStatusCodes.ERROR_DEVICE_NOT_BONDED;
- }
- if (!Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
- return BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION;
- }
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- return service.notifyActiveDeviceChangeApplied(device);
- }
-
- @Override
- public int isDualModeAudioEnabled(AttributionSource source) {
- AdapterService service = getService();
- if (service == null) {
- return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED;
- }
- if (!Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
- return BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION;
- }
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- if (!Utils.isDualModeAudioEnabled()) {
- return BluetoothStatusCodes.FEATURE_NOT_SUPPORTED;
- }
-
- return BluetoothStatusCodes.SUCCESS;
- }
-
- @Override
- public int registerPreferredAudioProfilesChangedCallback(
- IBluetoothPreferredAudioProfilesCallback callback, AttributionSource source) {
- AdapterService service = getService();
- if (service == null) {
- return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED;
- }
- if (!callerIsSystemOrActiveOrManagedUser(
- service, TAG, "registerPreferredAudioProfilesChangedCallback")) {
- return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ALLOWED;
- }
- requireNonNull(callback);
- if (!Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
- return BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION;
- }
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- // If LE only mode is enabled, the dual mode audio feature is disabled
- if (!Utils.isDualModeAudioEnabled()) {
- return BluetoothStatusCodes.FEATURE_NOT_SUPPORTED;
- }
-
- service.mPreferredAudioProfilesCallbacks.register(callback);
- return BluetoothStatusCodes.SUCCESS;
- }
-
- @Override
- public int unregisterPreferredAudioProfilesChangedCallback(
- IBluetoothPreferredAudioProfilesCallback callback, AttributionSource source) {
- AdapterService service = getService();
- if (service == null) {
- return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED;
- }
- if (!callerIsSystemOrActiveOrManagedUser(
- service, TAG, "unregisterPreferredAudioProfilesChangedCallback")) {
- return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ALLOWED;
- }
- requireNonNull(callback);
- if (!Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
- return BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION;
- }
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- if (!service.mPreferredAudioProfilesCallbacks.unregister(callback)) {
- Log.e(
- TAG,
- "unregisterPreferredAudioProfilesChangedCallback: callback was never "
- + "registered");
- return BluetoothStatusCodes.ERROR_CALLBACK_NOT_REGISTERED;
- }
- return BluetoothStatusCodes.SUCCESS;
- }
-
- @Override
- public int registerBluetoothQualityReportReadyCallback(
- IBluetoothQualityReportReadyCallback callback, AttributionSource source) {
- AdapterService service = getService();
- if (service == null) {
- return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED;
- }
- if (!callerIsSystemOrActiveOrManagedUser(
- service, TAG, "registerBluetoothQualityReportReadyCallback")) {
- return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ALLOWED;
- }
- requireNonNull(callback);
- if (!Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
- return BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION;
- }
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- service.mBluetoothQualityReportReadyCallbacks.register(callback);
- return BluetoothStatusCodes.SUCCESS;
- }
-
- @Override
- public int unregisterBluetoothQualityReportReadyCallback(
- IBluetoothQualityReportReadyCallback callback, AttributionSource source) {
- AdapterService service = getService();
- if (service == null) {
- return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED;
- }
- if (!callerIsSystemOrActiveOrManagedUser(
- service, TAG, "unregisterBluetoothQualityReportReadyCallback")) {
- return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ALLOWED;
- }
- requireNonNull(callback);
- if (!Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
- return BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION;
- }
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- if (!service.mBluetoothQualityReportReadyCallbacks.unregister(callback)) {
- Log.e(
- TAG,
- "unregisterBluetoothQualityReportReadyCallback: callback was never "
- + "registered");
- return BluetoothStatusCodes.ERROR_CALLBACK_NOT_REGISTERED;
- }
- return BluetoothStatusCodes.SUCCESS;
- }
-
- @Override
- public void registerHciVendorSpecificCallback(
- IBluetoothHciVendorSpecificCallback callback, int[] eventCodes) {
- AdapterService service = getService();
- if (service == null) {
- return;
- }
- if (!callerIsSystemOrActiveOrManagedUser(
- service, TAG, "registerHciVendorSpecificCallback")) {
- throw new SecurityException("not allowed");
- }
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- requireNonNull(callback);
- requireNonNull(eventCodes);
-
- Set<Integer> eventCodesSet =
- Arrays.stream(eventCodes).boxed().collect(Collectors.toSet());
- if (eventCodesSet.stream()
- .anyMatch((n) -> (n < 0) || (n >= 0x52 && n < 0x60) || (n > 0xff))) {
- throw new IllegalArgumentException("invalid vendor-specific event code");
- }
-
- service.mBluetoothHciVendorSpecificDispatcher.register(callback, eventCodesSet);
- }
-
- @Override
- public void unregisterHciVendorSpecificCallback(
- IBluetoothHciVendorSpecificCallback callback) {
- AdapterService service = getService();
- if (service == null) {
- return;
- }
- if (!callerIsSystemOrActiveOrManagedUser(
- service, TAG, "unregisterHciVendorSpecificCallback")) {
- throw new SecurityException("not allowed");
- }
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- requireNonNull(callback);
-
- service.mBluetoothHciVendorSpecificDispatcher.unregister(callback);
- }
-
- @Override
- public void sendHciVendorSpecificCommand(
- int ocf, byte[] parameters, IBluetoothHciVendorSpecificCallback callback) {
- AdapterService service = getService();
- if (service == null) {
- return;
- }
- if (!callerIsSystemOrActiveOrManagedUser(
- service, TAG, "sendHciVendorSpecificCommand")) {
- throw new SecurityException("not allowed");
- }
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- // Open this no-op android command for test purpose
- int getVendorCapabilitiesOcf = 0x153;
- if (ocf < 0
- || (ocf >= 0x150 && ocf < 0x160 && ocf != getVendorCapabilitiesOcf)
- || (ocf > 0x3ff)) {
- throw new IllegalArgumentException("invalid vendor-specific event code");
- }
- requireNonNull(parameters);
- if (parameters.length > 255) {
- throw new IllegalArgumentException("Parameters size is too big");
- }
-
- Optional<byte[]> cookie =
- service.mBluetoothHciVendorSpecificDispatcher.getRegisteredCookie(callback);
- if (!cookie.isPresent()) {
- Log.e(TAG, "send command without registered callback");
- throw new IllegalStateException("callback not registered");
- }
-
- service.mBluetoothHciVendorSpecificNativeInterface.sendCommand(
- ocf, parameters, cookie.get());
- }
-
- @Override
- public int getOffloadedTransportDiscoveryDataScanSupported(AttributionSource source) {
- AdapterService service = getService();
- if (service == null
- || !callerIsSystemOrActiveOrManagedUser(
- service, TAG, "getOffloadedTransportDiscoveryDataScanSupported")
- || !Utils.checkScanPermissionForDataDelivery(
- service, source, "getOffloadedTransportDiscoveryDataScanSupported")) {
- return BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_SCAN_PERMISSION;
- }
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- return service.getOffloadedTransportDiscoveryDataScanSupported();
- }
-
- @Override
- public boolean isMediaProfileConnected(AttributionSource source) {
- AdapterService service = getService();
- if (service == null
- || !Utils.checkConnectPermissionForDataDelivery(
- service, source, "AdapterService.isMediaProfileConnected")) {
- return false;
- }
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- return service.isMediaProfileConnected();
- }
-
- @Override
- public IBinder getBluetoothGatt() {
- AdapterService service = getService();
- return service == null ? null : service.getBluetoothGatt();
- }
-
- @Override
- public IBinder getBluetoothScan() {
- AdapterService service = getService();
- return service == null ? null : service.getBluetoothScan();
- }
-
- @Override
- public void unregAllGattClient(AttributionSource source) {
- AdapterService service = getService();
- if (service == null) {
- return;
- }
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- service.unregAllGattClient(source);
- }
-
- @Override
- public IBinder getProfile(int profileId) {
- AdapterService service = getService();
- if (service == null) {
- return null;
- }
-
- return service.getProfile(profileId);
- }
-
- @Override
- public int setActiveAudioDevicePolicy(
- BluetoothDevice device, int activeAudioDevicePolicy, AttributionSource source) {
- AdapterService service = getService();
- if (service == null) {
- return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED;
- }
- if (!callerIsSystemOrActiveOrManagedUser(service, TAG, "setActiveAudioDevicePolicy")) {
- return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ALLOWED;
- }
- if (!BluetoothAdapter.checkBluetoothAddress(device.getAddress())) {
- throw new IllegalArgumentException("device cannot have an invalid address");
- }
- if (!Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
- return BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- return service.mDatabaseManager.setActiveAudioDevicePolicy(
- device, activeAudioDevicePolicy);
- }
-
- @Override
- public int getActiveAudioDevicePolicy(BluetoothDevice device, AttributionSource source) {
- AdapterService service = getService();
- if (service == null) {
- return BluetoothDevice.ACTIVE_AUDIO_DEVICE_POLICY_DEFAULT;
- }
- if (!callerIsSystemOrActiveOrManagedUser(service, TAG, "getActiveAudioDevicePolicy")) {
- throw new IllegalStateException(
- "Caller is not the system or part of the active/managed user");
- }
- if (!BluetoothAdapter.checkBluetoothAddress(device.getAddress())) {
- throw new IllegalArgumentException("device cannot have an invalid address");
- }
- if (!Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
- return BluetoothDevice.ACTIVE_AUDIO_DEVICE_POLICY_DEFAULT;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- return service.mDatabaseManager.getActiveAudioDevicePolicy(device);
- }
-
- @Override
- public int setMicrophonePreferredForCalls(
- BluetoothDevice device, boolean enabled, AttributionSource source) {
- requireNonNull(device);
- AdapterService service = getService();
- if (service == null) {
- return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED;
- }
- if (!callerIsSystemOrActiveOrManagedUser(
- service, TAG, "setMicrophonePreferredForCalls")) {
- return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ALLOWED;
- }
- if (!BluetoothAdapter.checkBluetoothAddress(device.getAddress())) {
- throw new IllegalArgumentException("device cannot have an invalid address");
- }
- if (!Utils.checkConnectPermissionForDataDelivery(
- service, source, "AdapterService setMicrophonePreferredForCalls")) {
- return BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- return service.mDatabaseManager.setMicrophonePreferredForCalls(device, enabled);
- }
-
- @Override
- public boolean isMicrophonePreferredForCalls(
- BluetoothDevice device, AttributionSource source) {
- requireNonNull(device);
- AdapterService service = getService();
- if (service == null) {
- return true;
- }
- if (!callerIsSystemOrActiveOrManagedUser(
- service, TAG, "isMicrophonePreferredForCalls")) {
- throw new IllegalStateException(
- "Caller is not the system or part of the active/managed user");
- }
- if (!BluetoothAdapter.checkBluetoothAddress(device.getAddress())) {
- throw new IllegalArgumentException("device cannot have an invalid address");
- }
- if (!Utils.checkConnectPermissionForDataDelivery(
- service, source, "AdapterService isMicrophonePreferredForCalls")) {
- return true;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- return service.mDatabaseManager.isMicrophonePreferredForCalls(device);
- }
-
- @Override
- public boolean isLeCocSocketOffloadSupported(AttributionSource source) {
- AdapterService service = getService();
- if (service == null) {
- return false;
- }
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- return service.isLeCocSocketOffloadSupported();
- }
-
- @Override
- public boolean isRfcommSocketOffloadSupported(AttributionSource source) {
- AdapterService service = getService();
- if (service == null) {
- return false;
- }
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- return service.isRfcommSocketOffloadSupported();
- }
-
- @Override
- public IBinder getBluetoothAdvertise() {
- AdapterService service = getService();
- return service == null ? null : service.getBluetoothAdvertise();
- }
-
- @Override
- public IBinder getDistanceMeasurement() {
- AdapterService service = getService();
- return service == null ? null : service.getDistanceMeasurement();
- }
-
- @Override
- public int getKeyMissingCount(BluetoothDevice device, AttributionSource source) {
- AdapterService service = getService();
- if (service == null) {
- return -1;
- }
- if (!callerIsSystemOrActiveOrManagedUser(service, TAG, "getKeyMissingCount")) {
- throw new IllegalStateException(
- "Caller is not the system or part of the active/managed user");
- }
- if (!BluetoothAdapter.checkBluetoothAddress(device.getAddress())) {
- throw new IllegalArgumentException("device cannot have an invalid address");
- }
- if (!Utils.checkConnectPermissionForDataDelivery(
- service, source, "AdapterService getKeyMissingCount")) {
- return -1;
- }
-
- return service.mDatabaseManager.getKeyMissingCount(device);
- }
- }
-
- /**
* Gets the preferred audio profiles for the device. See {@link
* BluetoothAdapter#getPreferredAudioProfiles(BluetoothDevice)} for more details.
*
@@ -4430,7 +2265,7 @@ public class AdapterService extends Service {
* @param modeToProfileBundle is the preferences we want to set for the device
* @return whether the preferences were successfully requested
*/
- private int setPreferredAudioProfiles(BluetoothDevice device, Bundle modeToProfileBundle) {
+ int setPreferredAudioProfiles(BluetoothDevice device, Bundle modeToProfileBundle) {
Log.i(TAG, "setPreferredAudioProfiles for device=" + device);
if (!isDualModeAudioEnabled()) {
Log.e(TAG, "setPreferredAudioProfiles called while sysprop is disabled");
@@ -4650,7 +2485,7 @@ public class AdapterService extends Service {
* @param device the remote device whose preferred audio profiles have been changed
* @return whether the Bluetooth stack acknowledged the change successfully
*/
- private int notifyActiveDeviceChangeApplied(BluetoothDevice device) {
+ int notifyActiveDeviceChangeApplied(BluetoothDevice device) {
if (mLeAudioService == null) {
Log.e(TAG, "LE Audio profile not enabled");
return BluetoothStatusCodes.ERROR_PROFILE_NOT_CONNECTED;
@@ -4920,6 +2755,15 @@ public class AdapterService extends Service {
return new BluetoothAddress(identityAddress, identityAddressType);
}
+ public boolean addAssociatedPackage(BluetoothDevice device, String packageName) {
+ DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device);
+ if (deviceProp == null) {
+ return false;
+ }
+ deviceProp.addPackage(packageName);
+ return true;
+ }
+
private record CallerInfo(String callerPackageName, UserHandle user) {}
boolean createBond(
@@ -5369,35 +3213,32 @@ public class AdapterService extends Service {
Log.e(TAG, "setActiveDevice: Bluetooth is not enabled");
return false;
}
- boolean setA2dp = false;
boolean setHeadset = false;
+ boolean setA2dp = false;
// Determine for which profiles we want to set device as our active device
switch (profiles) {
- case BluetoothAdapter.ACTIVE_DEVICE_AUDIO:
- setA2dp = true;
- break;
- case BluetoothAdapter.ACTIVE_DEVICE_PHONE_CALL:
+ case BluetoothAdapter.ACTIVE_DEVICE_PHONE_CALL -> setHeadset = true;
+ case BluetoothAdapter.ACTIVE_DEVICE_AUDIO -> setA2dp = true;
+ case BluetoothAdapter.ACTIVE_DEVICE_ALL -> {
setHeadset = true;
- break;
- case BluetoothAdapter.ACTIVE_DEVICE_ALL:
setA2dp = true;
- setHeadset = true;
- break;
- default:
+ }
+ default -> {
return false;
+ }
}
- boolean a2dpSupported =
- mA2dpService != null
- && (device == null
- || mA2dpService.getConnectionPolicy(device)
- == CONNECTION_POLICY_ALLOWED);
boolean hfpSupported =
mHeadsetService != null
&& (device == null
|| mHeadsetService.getConnectionPolicy(device)
== CONNECTION_POLICY_ALLOWED);
+ boolean a2dpSupported =
+ mA2dpService != null
+ && (device == null
+ || mA2dpService.getConnectionPolicy(device)
+ == CONNECTION_POLICY_ALLOWED);
boolean leAudioSupported =
mLeAudioService != null
&& (device == null
@@ -5420,6 +3261,12 @@ public class AdapterService extends Service {
}
}
+ // Order matters, some devices do not accept A2DP connection before HFP connection
+ if (setHeadset && hfpSupported) {
+ Log.i(TAG, "setActiveDevice: Setting active Headset " + device);
+ mHeadsetService.setActiveDevice(device);
+ }
+
if (setA2dp && a2dpSupported) {
Log.i(TAG, "setActiveDevice: Setting active A2dp device " + device);
if (device == null) {
@@ -5451,11 +3298,6 @@ public class AdapterService extends Service {
}
}
- if (setHeadset && hfpSupported) {
- Log.i(TAG, "setActiveDevice: Setting active Headset " + device);
- mHeadsetService.setActiveDevice(device);
- }
-
return true;
}
@@ -5470,8 +3312,8 @@ public class AdapterService extends Service {
if (mLeAudioService == null) {
return false;
}
- boolean a2dpSupported = isProfileSupported(leAudioDevice, BluetoothProfile.A2DP);
boolean hfpSupported = isProfileSupported(leAudioDevice, BluetoothProfile.HEADSET);
+ boolean a2dpSupported = isProfileSupported(leAudioDevice, BluetoothProfile.A2DP);
List<BluetoothDevice> groupDevices = mLeAudioService.getGroupDevices(leAudioDevice);
if (hfpSupported && mHeadsetService != null) {
@@ -5577,26 +3419,11 @@ public class AdapterService extends Service {
return BluetoothStatusCodes.SUCCESS;
}
- /**
- * Connect all supported bluetooth profiles between the local and remote device
- *
- * @param device is the remote device with which to connect all supported profiles
- */
+ /** All profile toggles are disabled, so connects all supported profiles */
void connectAllSupportedProfiles(BluetoothDevice device) {
int numProfilesConnected = 0;
- // All profile toggles disabled, so connects all supported profiles
- if (mA2dpService != null && isProfileSupported(device, BluetoothProfile.A2DP)) {
- Log.i(TAG, "connectAllSupportedProfiles: Connecting A2dp");
- // Set connection policy also connects the profile with CONNECTION_POLICY_ALLOWED
- mA2dpService.setConnectionPolicy(device, CONNECTION_POLICY_ALLOWED);
- numProfilesConnected++;
- }
- if (mA2dpSinkService != null && isProfileSupported(device, BluetoothProfile.A2DP_SINK)) {
- Log.i(TAG, "connectAllSupportedProfiles: Connecting A2dp Sink");
- mA2dpSinkService.setConnectionPolicy(device, CONNECTION_POLICY_ALLOWED);
- numProfilesConnected++;
- }
+ // Order matters, some devices do not accept A2DP connection before HFP connection
if (mHeadsetService != null && isProfileSupported(device, BluetoothProfile.HEADSET)) {
Log.i(TAG, "connectAllSupportedProfiles: Connecting Headset Profile");
mHeadsetService.setConnectionPolicy(device, CONNECTION_POLICY_ALLOWED);
@@ -5608,6 +3435,17 @@ public class AdapterService extends Service {
mHeadsetClientService.setConnectionPolicy(device, CONNECTION_POLICY_ALLOWED);
numProfilesConnected++;
}
+ if (mA2dpService != null && isProfileSupported(device, BluetoothProfile.A2DP)) {
+ Log.i(TAG, "connectAllSupportedProfiles: Connecting A2dp");
+ // Set connection policy also connects the profile with CONNECTION_POLICY_ALLOWED
+ mA2dpService.setConnectionPolicy(device, CONNECTION_POLICY_ALLOWED);
+ numProfilesConnected++;
+ }
+ if (mA2dpSinkService != null && isProfileSupported(device, BluetoothProfile.A2DP_SINK)) {
+ Log.i(TAG, "connectAllSupportedProfiles: Connecting A2dp Sink");
+ mA2dpSinkService.setConnectionPolicy(device, CONNECTION_POLICY_ALLOWED);
+ numProfilesConnected++;
+ }
if (mMapClientService != null && isProfileSupported(device, BluetoothProfile.MAP_CLIENT)) {
Log.i(TAG, "connectAllSupportedProfiles: Connecting MAP");
mMapClientService.setConnectionPolicy(device, CONNECTION_POLICY_ALLOWED);
@@ -5696,18 +3534,6 @@ public class AdapterService extends Service {
return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED;
}
- if (mA2dpService != null
- && (mA2dpService.getConnectionState(device) == STATE_CONNECTED
- || mA2dpService.getConnectionState(device) == STATE_CONNECTING)) {
- Log.i(TAG, "disconnectAllEnabledProfiles: Disconnecting A2dp");
- mA2dpService.disconnect(device);
- }
- if (mA2dpSinkService != null
- && (mA2dpSinkService.getConnectionState(device) == STATE_CONNECTED
- || mA2dpSinkService.getConnectionState(device) == STATE_CONNECTING)) {
- Log.i(TAG, "disconnectAllEnabledProfiles: Disconnecting A2dp Sink");
- mA2dpSinkService.disconnect(device);
- }
if (mHeadsetService != null
&& (mHeadsetService.getConnectionState(device) == STATE_CONNECTED
|| mHeadsetService.getConnectionState(device) == STATE_CONNECTING)) {
@@ -5720,6 +3546,18 @@ public class AdapterService extends Service {
Log.i(TAG, "disconnectAllEnabledProfiles: Disconnecting HFP");
mHeadsetClientService.disconnect(device);
}
+ if (mA2dpService != null
+ && (mA2dpService.getConnectionState(device) == STATE_CONNECTED
+ || mA2dpService.getConnectionState(device) == STATE_CONNECTING)) {
+ Log.i(TAG, "disconnectAllEnabledProfiles: Disconnecting A2dp");
+ mA2dpService.disconnect(device);
+ }
+ if (mA2dpSinkService != null
+ && (mA2dpSinkService.getConnectionState(device) == STATE_CONNECTED
+ || mA2dpSinkService.getConnectionState(device) == STATE_CONNECTING)) {
+ Log.i(TAG, "disconnectAllEnabledProfiles: Disconnecting A2dp Sink");
+ mA2dpSinkService.disconnect(device);
+ }
if (mMapClientService != null
&& (mMapClientService.getConnectionState(device) == STATE_CONNECTED
|| mMapClientService.getConnectionState(device) == STATE_CONNECTING)) {
@@ -6106,27 +3944,22 @@ public class AdapterService extends Service {
mLocalCallbacks.remove(callback);
}
- @VisibleForTesting
void registerRemoteCallback(IBluetoothCallback callback) {
mSystemServerCallbacks.register(callback);
}
- @VisibleForTesting
void unregisterRemoteCallback(IBluetoothCallback callback) {
mSystemServerCallbacks.unregister(callback);
}
- @VisibleForTesting
void bleOnToOn() {
mAdapterStateMachine.sendMessage(AdapterState.USER_TURN_ON);
}
- @VisibleForTesting
void bleOnToOff() {
mAdapterStateMachine.sendMessage(AdapterState.BLE_TURN_OFF);
}
- @VisibleForTesting
boolean factoryReset() {
mDatabaseManager.factoryReset();
@@ -6145,12 +3978,11 @@ public class AdapterService extends Service {
return mNativeInterface.factoryReset();
}
- @VisibleForTesting
int getScanMode() {
return mScanMode;
}
- private boolean setScanMode(int mode, String from) {
+ boolean setScanMode(int mode, String from) {
mScanModeChanges.add(from + ": " + scanModeName(mode));
if (!mNativeInterface.setScanMode(convertScanModeToHal(mode))) {
return false;
@@ -6164,7 +3996,6 @@ public class AdapterService extends Service {
return true;
}
- @VisibleForTesting
BluetoothActivityEnergyInfo reportActivityInfo() {
if (mAdapterProperties.getState() != BluetoothAdapter.STATE_ON
|| !mAdapterProperties.isActivityAndEnergyReportingSupported()) {
@@ -6379,12 +4210,12 @@ public class AdapterService extends Service {
/** Handle Bluetooth profiles when bond state changes with a {@link BluetoothDevice} */
public void handleBondStateChanged(BluetoothDevice device, int fromState, int toState) {
- if (mA2dpService != null && mA2dpService.isAvailable()) {
- mA2dpService.handleBondStateChanged(device, fromState, toState);
- }
if (mHeadsetService != null && mHeadsetService.isAvailable()) {
mHeadsetService.handleBondStateChanged(device, fromState, toState);
}
+ if (mA2dpService != null && mA2dpService.isAvailable()) {
+ mA2dpService.handleBondStateChanged(device, fromState, toState);
+ }
if (mLeAudioService != null && mLeAudioService.isAvailable()) {
mLeAudioService.handleBondStateChanged(device, fromState, toState);
}
@@ -6610,10 +4441,6 @@ public class AdapterService extends Service {
return BluetoothProperties.getHardwareOperatingVoltageMv().orElse(0) / 1000.0;
}
- public RemoteDevices getRemoteDevices() {
- return mRemoteDevices;
- }
-
private static String scanModeName(int scanMode) {
return switch (scanMode) {
case SCAN_MODE_NONE -> "SCAN_MODE_NONE";
@@ -6702,14 +4529,6 @@ public class AdapterService extends Service {
}
}
- @SuppressLint("AndroidFrameworkRequiresPermission")
- private void enforceBluetoothPrivilegedPermissionIfNeeded(
- OobData remoteP192Data, OobData remoteP256Data) {
- if (remoteP192Data != null || remoteP256Data != null) {
- this.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- }
- }
-
private final Object mDeviceConfigLock = new Object();
/**
diff --git a/android/app/src/com/android/bluetooth/btservice/AdapterServiceBinder.java b/android/app/src/com/android/bluetooth/btservice/AdapterServiceBinder.java
new file mode 100644
index 0000000000..aff6642b7d
--- /dev/null
+++ b/android/app/src/com/android/bluetooth/btservice/AdapterServiceBinder.java
@@ -0,0 +1,2262 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.bluetooth.btservice;
+
+import static android.Manifest.permission.BLUETOOTH_PRIVILEGED;
+import static android.Manifest.permission.DUMP;
+import static android.Manifest.permission.LOCAL_MAC_ADDRESS;
+import static android.Manifest.permission.MODIFY_PHONE_STATE;
+import static android.bluetooth.BluetoothAdapter.SCAN_MODE_NONE;
+import static android.bluetooth.BluetoothDevice.TRANSPORT_AUTO;
+import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTED;
+
+import static com.android.bluetooth.ChangeIds.ENFORCE_CONNECT;
+import static com.android.bluetooth.Utils.callerIsSystem;
+import static com.android.bluetooth.Utils.callerIsSystemOrActiveOrManagedUser;
+import static com.android.bluetooth.Utils.checkConnectPermissionForDataDelivery;
+import static com.android.bluetooth.Utils.checkScanPermissionForDataDelivery;
+import static com.android.bluetooth.Utils.getBytesFromAddress;
+import static com.android.bluetooth.Utils.getUidPidString;
+
+import static java.util.Objects.requireNonNull;
+
+import android.annotation.NonNull;
+import android.app.PendingIntent;
+import android.app.compat.CompatChanges;
+import android.bluetooth.BluetoothActivityEnergyInfo;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothAdapter.ActiveDeviceProfile;
+import android.bluetooth.BluetoothAdapter.ActiveDeviceUse;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothDevice.BluetoothAddress;
+import android.bluetooth.BluetoothProfile;
+import android.bluetooth.BluetoothProtoEnums;
+import android.bluetooth.BluetoothSinkAudioPolicy;
+import android.bluetooth.BluetoothStatusCodes;
+import android.bluetooth.IBluetooth;
+import android.bluetooth.IBluetoothActivityEnergyInfoListener;
+import android.bluetooth.IBluetoothCallback;
+import android.bluetooth.IBluetoothConnectionCallback;
+import android.bluetooth.IBluetoothHciVendorSpecificCallback;
+import android.bluetooth.IBluetoothMetadataListener;
+import android.bluetooth.IBluetoothOobDataCallback;
+import android.bluetooth.IBluetoothPreferredAudioProfilesCallback;
+import android.bluetooth.IBluetoothQualityReportReadyCallback;
+import android.bluetooth.IBluetoothSocketManager;
+import android.bluetooth.IncomingRfcommSocketInfo;
+import android.bluetooth.OobData;
+import android.content.AttributionSource;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.ParcelUuid;
+import android.os.Process;
+import android.os.RemoteCallbackList;
+import android.os.RemoteException;
+import android.util.Log;
+
+import com.android.bluetooth.BluetoothStatsLog;
+import com.android.bluetooth.Utils;
+import com.android.bluetooth.btservice.RemoteDevices.DeviceProperties;
+import com.android.bluetooth.flags.Flags;
+import com.android.modules.expresslog.Counter;
+
+import libcore.util.SneakyThrow;
+
+import java.io.FileDescriptor;
+import java.io.FileOutputStream;
+import java.io.PrintWriter;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.CompletableFuture;
+import java.util.stream.Collectors;
+
+/**
+ * There is no leak of this binder since it is never re-used and the process is systematically
+ * killed
+ */
+class AdapterServiceBinder extends IBluetooth.Stub {
+ private static final String TAG =
+ Utils.TAG_PREFIX_BLUETOOTH + AdapterServiceBinder.class.getSimpleName();
+
+ private static final int MIN_ADVT_INSTANCES_FOR_MA = 5;
+ private static final int MIN_OFFLOADED_FILTERS = 10;
+ private static final int MIN_OFFLOADED_SCAN_STORAGE_BYTES = 1024;
+
+ private final AdapterService mService;
+
+ AdapterServiceBinder(AdapterService svc) {
+ mService = svc;
+ }
+
+ public AdapterService getService() {
+ if (!mService.isAvailable()) {
+ return null;
+ }
+ return mService;
+ }
+
+ @Override
+ public int getState() {
+ AdapterService service = getService();
+ if (service == null) {
+ return BluetoothAdapter.STATE_OFF;
+ }
+
+ return service.getState();
+ }
+
+ @Override
+ public void killBluetoothProcess() {
+ mService.enforceCallingPermission(BLUETOOTH_PRIVILEGED, null);
+
+ Runnable killAction =
+ () -> {
+ if (Flags.killInsteadOfExit()) {
+ Log.i(TAG, "killBluetoothProcess: Calling killProcess(myPid())");
+ Process.killProcess(Process.myPid());
+ } else {
+ Log.i(TAG, "killBluetoothProcess: Calling System.exit");
+ System.exit(0);
+ }
+ };
+
+ // Post on the main handler to let the cleanup complete before calling exit
+ mService.getHandler().post(killAction);
+
+ try {
+ // Wait for Bluetooth to be killed from its main thread
+ Thread.sleep(1_000); // SystemServer is waiting 2000 ms, we need to wait less here
+ } catch (InterruptedException e) {
+ Log.e(TAG, "killBluetoothProcess: Interrupted while waiting for kill");
+ }
+
+ // Bluetooth cannot be killed on the main thread; it is in a deadLock.
+ // Trying to recover by killing the Bluetooth from the binder thread.
+ // This is bad :(
+ Counter.logIncrement("bluetooth.value_kill_from_binder_thread");
+ Log.wtf(TAG, "Failed to kill Bluetooth using its main thread. Trying from binder");
+ killAction.run();
+ }
+
+ @Override
+ public void offToBleOn(boolean quietMode, AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "offToBleOn")) {
+ return;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ service.offToBleOn(quietMode);
+ }
+
+ @Override
+ public void onToBleOn(AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "onToBleOn")) {
+ return;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ service.onToBleOn();
+ }
+
+ @Override
+ public String getAddress(AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null
+ || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getAddress")
+ || !checkConnectPermissionForDataDelivery(service, source, TAG, "getAddress")) {
+ return null;
+ }
+
+ service.enforceCallingOrSelfPermission(LOCAL_MAC_ADDRESS, null);
+ return Utils.getAddressStringFromByte(service.getAdapterProperties().getAddress());
+ }
+
+ @Override
+ public List<ParcelUuid> getUuids(AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null
+ || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getUuids")
+ || !checkConnectPermissionForDataDelivery(service, source, TAG, "getUuids")) {
+ return Collections.emptyList();
+ }
+
+ ParcelUuid[] parcels = service.getAdapterProperties().getUuids();
+ if (parcels == null) {
+ parcels = new ParcelUuid[0];
+ }
+ return Arrays.asList(parcels);
+ }
+
+ @Override
+ public String getIdentityAddress(String address) {
+ AdapterService service = getService();
+ if (service == null
+ || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getIdentityAddress")
+ || !checkConnectPermissionForDataDelivery(
+ service,
+ Utils.getCallingAttributionSource(mService),
+ TAG,
+ "getIdentityAddress")) {
+ return null;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.getIdentityAddress(address);
+ }
+
+ @Override
+ @NonNull
+ public BluetoothAddress getIdentityAddressWithType(@NonNull String address) {
+ AdapterService service = getService();
+ if (service == null
+ || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getIdentityAddressWithType")
+ || !checkConnectPermissionForDataDelivery(
+ service,
+ Utils.getCallingAttributionSource(mService),
+ TAG,
+ "getIdentityAddressWithType")) {
+ return new BluetoothAddress(null, BluetoothDevice.ADDRESS_TYPE_UNKNOWN);
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.getIdentityAddressWithType(address);
+ }
+
+ @Override
+ public String getName(AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null
+ || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getName")
+ || !checkConnectPermissionForDataDelivery(service, source, TAG, "getName")) {
+ return null;
+ }
+
+ return service.getName();
+ }
+
+ @Override
+ public int getNameLengthForAdvertise(AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null
+ || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getNameLengthForAdvertise")
+ || !Utils.checkAdvertisePermissionForDataDelivery(service, source, TAG)) {
+ return -1;
+ }
+
+ return service.getNameLengthForAdvertise();
+ }
+
+ @Override
+ public boolean setName(String name, AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null
+ || !callerIsSystemOrActiveOrManagedUser(service, TAG, "setName")
+ || !checkConnectPermissionForDataDelivery(service, source, TAG, "setName")) {
+ return false;
+ }
+
+ if (Flags.emptyNamesAreInvalid()) {
+ requireNonNull(name);
+ name = name.trim();
+ if (name.isEmpty()) {
+ throw new IllegalArgumentException("Empty names are not valid");
+ }
+ }
+
+ Log.d(TAG, "AdapterServiceBinder.setName(" + name + ")");
+ return service.getAdapterProperties().setName(name);
+ }
+
+ @Override
+ public int getScanMode(AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null
+ || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getScanMode")
+ || !checkScanPermissionForDataDelivery(service, source, TAG, "getScanMode")) {
+ return SCAN_MODE_NONE;
+ }
+
+ return service.getScanMode();
+ }
+
+ @Override
+ public int setScanMode(int mode, AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null
+ || !callerIsSystemOrActiveOrManagedUser(service, TAG, "setScanMode")
+ || !checkScanPermissionForDataDelivery(service, source, TAG, "setScanMode")) {
+ return BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_SCAN_PERMISSION;
+ }
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+
+ String logCaller = getUidPidString() + " packageName=" + source.getPackageName();
+ CompletableFuture<Boolean> future = new CompletableFuture<>();
+ mService.getHandler()
+ .post(
+ () ->
+ future.complete(
+ service.getState() == BluetoothAdapter.STATE_ON
+ && service.setScanMode(mode, logCaller)));
+ return future.join() ? BluetoothStatusCodes.SUCCESS : BluetoothStatusCodes.ERROR_UNKNOWN;
+ }
+
+ @Override
+ public long getDiscoverableTimeout(AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null
+ || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getDiscoverableTimeout")
+ || !checkScanPermissionForDataDelivery(
+ service, source, TAG, "getDiscoverableTimeout")) {
+ return -1;
+ }
+
+ return service.getAdapterProperties().getDiscoverableTimeout();
+ }
+
+ @Override
+ public int setDiscoverableTimeout(long timeout, AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null
+ || !callerIsSystemOrActiveOrManagedUser(service, TAG, "setDiscoverableTimeout")
+ || !checkScanPermissionForDataDelivery(
+ service, source, TAG, "setDiscoverableTimeout")) {
+ return BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_SCAN_PERMISSION;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.getAdapterProperties().setDiscoverableTimeout((int) timeout)
+ ? BluetoothStatusCodes.SUCCESS
+ : BluetoothStatusCodes.ERROR_UNKNOWN;
+ }
+
+ @Override
+ public boolean startDiscovery(AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null
+ || !callerIsSystemOrActiveOrManagedUser(service, TAG, "startDiscovery")
+ || !checkScanPermissionForDataDelivery(service, source, TAG, "startDiscovery")) {
+ return false;
+ }
+
+ Log.i(TAG, "startDiscovery: from " + getUidPidString());
+ return service.startDiscovery(source);
+ }
+
+ @Override
+ public boolean cancelDiscovery(AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null
+ || !callerIsSystemOrActiveOrManagedUser(service, TAG, "cancelDiscovery")
+ || !checkScanPermissionForDataDelivery(service, source, TAG, "cancelDiscovery")) {
+ return false;
+ }
+
+ Log.i(TAG, "cancelDiscovery: from " + getUidPidString());
+ return service.getNative().cancelDiscovery();
+ }
+
+ @Override
+ public boolean isDiscovering(AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null
+ || !callerIsSystemOrActiveOrManagedUser(service, TAG, "isDiscovering")
+ || !checkScanPermissionForDataDelivery(service, source, TAG, "isDiscovering")) {
+ return false;
+ }
+
+ return service.getAdapterProperties().isDiscovering();
+ }
+
+ @Override
+ public long getDiscoveryEndMillis(AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null
+ || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getDiscoveryEndMillis")
+ || !checkConnectPermissionForDataDelivery(
+ service, source, TAG, "getDiscoveryEndMillis")) {
+ return -1;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+
+ return service.getAdapterProperties().discoveryEndMillis();
+ }
+
+ @Override
+ public List<BluetoothDevice> getMostRecentlyConnectedDevices(AttributionSource source) {
+ // don't check caller, may be called from system UI
+ AdapterService service = getService();
+ if (service == null
+ || !checkConnectPermissionForDataDelivery(
+ service, source, TAG, "getMostRecentlyConnectedDevices")) {
+ return Collections.emptyList();
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+
+ return service.getDatabaseManager().getMostRecentlyConnectedDevices();
+ }
+
+ @Override
+ public List<BluetoothDevice> getBondedDevices(AttributionSource source) {
+ // don't check caller, may be called from system UI
+ AdapterService service = getService();
+ if (service == null
+ || !checkConnectPermissionForDataDelivery(
+ service, source, TAG, "getBondedDevices")) {
+ return Collections.emptyList();
+ }
+
+ return Arrays.asList(service.getBondedDevices());
+ }
+
+ @Override
+ public int getAdapterConnectionState() {
+ // don't check caller, may be called from system UI
+ AdapterService service = getService();
+ if (service == null) {
+ return BluetoothAdapter.STATE_DISCONNECTED;
+ }
+
+ return service.getAdapterProperties().getConnectionState();
+ }
+
+ /**
+ * This method has an associated binder cache. The invalidation methods must be changed if the
+ * logic behind this method changes.
+ */
+ @Override
+ public int getProfileConnectionState(int profile, AttributionSource source) {
+ AdapterService service = getService();
+ boolean checkConnect = false;
+ final int callingUid = Binder.getCallingUid();
+ final long token = Binder.clearCallingIdentity();
+ try {
+ checkConnect = CompatChanges.isChangeEnabled(ENFORCE_CONNECT, callingUid);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ if (service == null
+ || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getProfileConnectionState")
+ || (checkConnect
+ && !checkConnectPermissionForDataDelivery(
+ service, source, TAG, "getProfileConnectionState"))) {
+ return STATE_DISCONNECTED;
+ }
+
+ return service.getAdapterProperties().getProfileConnectionState(profile);
+ }
+
+ @Override
+ public boolean createBond(BluetoothDevice device, int transport, AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null
+ || !callerIsSystemOrActiveOrManagedUser(service, TAG, "createBond")
+ || !checkConnectPermissionForDataDelivery(service, source, TAG, "createBond")) {
+ return false;
+ }
+
+ Log.i(
+ TAG,
+ "createBond:"
+ + (" device=" + device)
+ + (" transport=" + transport)
+ + (" from " + getUidPidString()));
+ return service.createBond(device, transport, null, null, source.getPackageName());
+ }
+
+ @Override
+ public boolean createBondOutOfBand(
+ BluetoothDevice device,
+ int transport,
+ OobData remoteP192Data,
+ OobData remoteP256Data,
+ AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null
+ || !callerIsSystemOrActiveOrManagedUser(service, TAG, "createBondOutOfBand")
+ || !checkConnectPermissionForDataDelivery(
+ service, source, TAG, "createBondOutOfBand")) {
+ return false;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+
+ Log.i(
+ TAG,
+ "createBondOutOfBand:"
+ + (" device=" + device)
+ + (" transport=" + transport)
+ + (" from " + getUidPidString()));
+ return service.createBond(
+ device, transport, remoteP192Data, remoteP256Data, source.getPackageName());
+ }
+
+ @Override
+ public boolean cancelBondProcess(BluetoothDevice device, AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null
+ || !callerIsSystemOrActiveOrManagedUser(service, TAG, "cancelBondProcess")
+ || !checkConnectPermissionForDataDelivery(
+ service, source, TAG, "cancelBondProcess")) {
+ return false;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+
+ Log.i(TAG, "cancelBondProcess: device=" + device + ", from " + getUidPidString());
+
+ DeviceProperties deviceProp = service.getRemoteDevices().getDeviceProperties(device);
+ if (deviceProp != null) {
+ deviceProp.setBondingInitiatedLocally(false);
+ }
+
+ service.logUserBondResponse(device, false, source);
+ return service.getNative().cancelBond(getBytesFromAddress(device.getAddress()));
+ }
+
+ @Override
+ public boolean removeBond(BluetoothDevice device, AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null
+ || !callerIsSystemOrActiveOrManagedUser(service, TAG, "removeBond")
+ || !checkConnectPermissionForDataDelivery(service, source, TAG, "removeBond")) {
+ return false;
+ }
+
+ Log.i(TAG, "removeBond: device=" + device + ", from " + getUidPidString());
+
+ DeviceProperties deviceProp = service.getRemoteDevices().getDeviceProperties(device);
+ if (deviceProp == null || deviceProp.getBondState() != BluetoothDevice.BOND_BONDED) {
+ Log.w(
+ TAG,
+ device
+ + " cannot be removed since "
+ + ((deviceProp == null)
+ ? "properties are empty"
+ : "bond state is " + deviceProp.getBondState()));
+ return false;
+ }
+ service.logUserBondResponse(device, false, source);
+ service.getBondAttemptCallerInfo().remove(device.getAddress());
+ service.getPhonePolicy().ifPresent(policy -> policy.onRemoveBondRequest(device));
+ deviceProp.setBondingInitiatedLocally(false);
+
+ Message msg = service.getBondStateMachine().obtainMessage(BondStateMachine.REMOVE_BOND);
+ msg.obj = device;
+ service.getBondStateMachine().sendMessage(msg);
+ return true;
+ }
+
+ @Override
+ public int getBondState(BluetoothDevice device, AttributionSource source) {
+ // don't check caller, may be called from system UI
+ AdapterService service = getService();
+ if (service == null
+ || !checkConnectPermissionForDataDelivery(service, source, TAG, "getBondState")) {
+ return BluetoothDevice.BOND_NONE;
+ }
+
+ return service.getBondState(device);
+ }
+
+ @Override
+ public boolean isBondingInitiatedLocally(BluetoothDevice device, AttributionSource source) {
+ // don't check caller, may be called from system UI
+ AdapterService service = getService();
+ if (service == null
+ || !checkConnectPermissionForDataDelivery(
+ service, source, TAG, "isBondingInitiatedLocally")) {
+ return false;
+ }
+
+ DeviceProperties deviceProp = service.getRemoteDevices().getDeviceProperties(device);
+ return deviceProp != null && deviceProp.isBondingInitiatedLocally();
+ }
+
+ @Override
+ public void generateLocalOobData(
+ int transport, IBluetoothOobDataCallback callback, AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null
+ || !callerIsSystemOrActiveOrManagedUser(service, TAG, "generateLocalOobData")
+ || !checkConnectPermissionForDataDelivery(
+ service, source, TAG, "generateLocalOobData")) {
+ return;
+ }
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ service.generateLocalOobData(transport, callback);
+ }
+
+ @Override
+ public long getSupportedProfiles(AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null
+ || !checkConnectPermissionForDataDelivery(
+ service, source, TAG, "getSupportedProfiles")) {
+ return 0;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return Config.getSupportedProfilesBitMask();
+ }
+
+ @Override
+ public int getConnectionState(BluetoothDevice device, AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null
+ || !checkConnectPermissionForDataDelivery(
+ service, source, TAG, "getConnectionState")) {
+ return BluetoothDevice.CONNECTION_STATE_DISCONNECTED;
+ }
+
+ return service.getConnectionState(device);
+ }
+
+ @Override
+ public int getConnectionHandle(
+ BluetoothDevice device, int transport, AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null
+ || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getConnectionHandle")
+ || !checkConnectPermissionForDataDelivery(
+ service, source, TAG, "getConnectionHandle")) {
+ return BluetoothDevice.ERROR;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.getConnectionHandle(device, transport);
+ }
+
+ @Override
+ public boolean canBondWithoutDialog(BluetoothDevice device, AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null
+ || !checkConnectPermissionForDataDelivery(
+ service, source, TAG, "canBondWithoutDialog")) {
+ return false;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.canBondWithoutDialog(device);
+ }
+
+ @Override
+ public String getPackageNameOfBondingApplication(
+ BluetoothDevice device, AttributionSource source) {
+ AdapterService service = getService();
+
+ if (service == null
+ || !checkConnectPermissionForDataDelivery(
+ service, source, TAG, "getPackageNameOfBondingApplication")) {
+ return null;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.getPackageNameOfBondingApplication(device);
+ }
+
+ @Override
+ public boolean removeActiveDevice(@ActiveDeviceUse int profiles, AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null
+ || !callerIsSystemOrActiveOrManagedUser(service, TAG, "removeActiveDevice")
+ || !checkConnectPermissionForDataDelivery(
+ service, source, TAG, "removeActiveDevice")) {
+ return false;
+ }
+
+ service.enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, null);
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+
+ Log.i(TAG, "removeActiveDevice: profiles=" + profiles + ", from " + getUidPidString());
+ return service.setActiveDevice(null, profiles);
+ }
+
+ @Override
+ public boolean setActiveDevice(
+ BluetoothDevice device, @ActiveDeviceUse int profiles, AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null
+ || !callerIsSystemOrActiveOrManagedUser(service, TAG, "setActiveDevice")
+ || !checkConnectPermissionForDataDelivery(
+ service, source, TAG, "setActiveDevice")) {
+ return false;
+ }
+
+ service.enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, null);
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+
+ Log.i(
+ TAG,
+ "setActiveDevice: device="
+ + device
+ + ", profiles="
+ + profiles
+ + ", from "
+ + getUidPidString());
+
+ return service.setActiveDevice(device, profiles);
+ }
+
+ @Override
+ public List<BluetoothDevice> getActiveDevices(
+ @ActiveDeviceProfile int profile, AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null
+ || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getActiveDevices")
+ || !checkConnectPermissionForDataDelivery(
+ service, source, TAG, "getActiveDevices")) {
+ return Collections.emptyList();
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.getActiveDevices(profile);
+ }
+
+ @Override
+ public int connectAllEnabledProfiles(BluetoothDevice device, AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null || !service.isEnabled()) {
+ return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED;
+ }
+ if (!callerIsSystemOrActiveOrManagedUser(service, TAG, "connectAllEnabledProfiles")) {
+ return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ALLOWED;
+ }
+ if (device == null) {
+ throw new IllegalArgumentException("device cannot be null");
+ }
+ if (!BluetoothAdapter.checkBluetoothAddress(device.getAddress())) {
+ throw new IllegalArgumentException("device cannot have an invalid address");
+ }
+ if (!checkConnectPermissionForDataDelivery(
+ service, source, TAG, "connectAllEnabledProfiles")) {
+ return BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION;
+ }
+
+ service.enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, null);
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+
+ Log.i(TAG, "connectAllEnabledProfiles: device=" + device + ", from " + getUidPidString());
+ MetricsLogger.getInstance()
+ .logBluetoothEvent(
+ device,
+ BluetoothStatsLog
+ .BLUETOOTH_CROSS_LAYER_EVENT_REPORTED__EVENT_TYPE__INITIATOR_CONNECTION,
+ BluetoothStatsLog.BLUETOOTH_CROSS_LAYER_EVENT_REPORTED__STATE__START,
+ source.getUid());
+
+ try {
+ return service.connectAllEnabledProfiles(device);
+ } catch (Exception e) {
+ Log.v(TAG, "connectAllEnabledProfiles() failed", e);
+ SneakyThrow.sneakyThrow(e);
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public int disconnectAllEnabledProfiles(BluetoothDevice device, AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null) {
+ return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED;
+ }
+ if (!callerIsSystemOrActiveOrManagedUser(service, TAG, "disconnectAllEnabledProfiles")) {
+ return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ALLOWED;
+ }
+ if (device == null) {
+ throw new IllegalArgumentException("device cannot be null");
+ }
+ if (!BluetoothAdapter.checkBluetoothAddress(device.getAddress())) {
+ throw new IllegalArgumentException("device cannot have an invalid address");
+ }
+ if (!checkConnectPermissionForDataDelivery(
+ service, source, TAG, "disconnectAllEnabledProfiles")) {
+ return BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+
+ Log.i(
+ TAG,
+ "disconnectAllEnabledProfiles: device=" + device + ", from " + getUidPidString());
+
+ try {
+ return service.disconnectAllEnabledProfiles(device);
+ } catch (Exception e) {
+ Log.v(TAG, "disconnectAllEnabledProfiles() failed", e);
+ SneakyThrow.sneakyThrow(e);
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public String getRemoteName(BluetoothDevice device, AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null
+ || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getRemoteName")
+ || !checkConnectPermissionForDataDelivery(service, source, TAG, "getRemoteName")) {
+ return null;
+ }
+
+ return service.getRemoteName(device);
+ }
+
+ @Override
+ public int getRemoteType(BluetoothDevice device, AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null
+ || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getRemoteType")
+ || !checkConnectPermissionForDataDelivery(service, source, TAG, "getRemoteType")) {
+ return BluetoothDevice.DEVICE_TYPE_UNKNOWN;
+ }
+
+ return service.getRemoteType(device);
+ }
+
+ @Override
+ public String getRemoteAlias(BluetoothDevice device, AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null
+ || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getRemoteAlias")
+ || !checkConnectPermissionForDataDelivery(service, source, TAG, "getRemoteAlias")) {
+ return null;
+ }
+
+ DeviceProperties deviceProp = service.getRemoteDevices().getDeviceProperties(device);
+ return deviceProp != null ? deviceProp.getAlias() : null;
+ }
+
+ @Override
+ public int setRemoteAlias(BluetoothDevice device, String name, AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null) {
+ return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED;
+ }
+ if (!callerIsSystemOrActiveOrManagedUser(service, TAG, "setRemoteAlias")) {
+ return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ALLOWED;
+ }
+ if (name != null && name.isEmpty()) {
+ throw new IllegalArgumentException("alias cannot be the empty string");
+ }
+
+ if (!checkConnectPermissionForDataDelivery(service, source, TAG, "setRemoteAlias")) {
+ return BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION;
+ }
+
+ Utils.enforceCdmAssociationIfNotBluetoothPrivileged(
+ service, service.getCompanionDeviceManager(), source, device);
+
+ DeviceProperties deviceProp = service.getRemoteDevices().getDeviceProperties(device);
+ if (deviceProp == null) {
+ return BluetoothStatusCodes.ERROR_DEVICE_NOT_BONDED;
+ }
+ deviceProp.setAlias(device, name);
+ return BluetoothStatusCodes.SUCCESS;
+ }
+
+ @Override
+ public int getRemoteClass(BluetoothDevice device, AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null
+ || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getRemoteClass")
+ || !checkConnectPermissionForDataDelivery(service, source, TAG, "getRemoteClass")) {
+ return 0;
+ }
+
+ return service.getRemoteClass(device);
+ }
+
+ @Override
+ public List<ParcelUuid> getRemoteUuids(BluetoothDevice device, AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null
+ || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getRemoteUuids")
+ || !checkConnectPermissionForDataDelivery(service, source, TAG, "getRemoteUuids")) {
+ return Collections.emptyList();
+ }
+
+ final ParcelUuid[] parcels = service.getRemoteUuids(device);
+ if (parcels == null) {
+ return null;
+ }
+ return Arrays.asList(parcels);
+ }
+
+ @Override
+ public boolean fetchRemoteUuids(
+ BluetoothDevice device, int transport, AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null
+ || !callerIsSystemOrActiveOrManagedUser(service, TAG, "fetchRemoteUuids")
+ || !checkConnectPermissionForDataDelivery(
+ service, source, TAG, "fetchRemoteUuids")) {
+ return false;
+ }
+ if (transport != TRANSPORT_AUTO) {
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ }
+
+ Log.i(
+ TAG,
+ "fetchRemoteUuids: device="
+ + device
+ + ", transport="
+ + transport
+ + ", from "
+ + getUidPidString());
+
+ service.getRemoteDevices().fetchUuids(device, transport);
+ MetricsLogger.getInstance().cacheCount(BluetoothProtoEnums.SDP_FETCH_UUID_REQUEST, 1);
+ return true;
+ }
+
+ @Override
+ public boolean setPin(
+ BluetoothDevice device,
+ boolean accept,
+ int len,
+ byte[] pinCode,
+ AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null
+ || !callerIsSystemOrActiveOrManagedUser(service, TAG, "setPin")
+ || !checkConnectPermissionForDataDelivery(service, source, TAG, "setPin")) {
+ return false;
+ }
+
+ DeviceProperties deviceProp = service.getRemoteDevices().getDeviceProperties(device);
+ // Only allow setting a pin in bonding state, or bonded state in case of security
+ // upgrade.
+ if (deviceProp == null || !deviceProp.isBondingOrBonded()) {
+ Log.e(TAG, "setPin: device=" + device + ", not bonding");
+ return false;
+ }
+ if (pinCode.length != len) {
+ android.util.EventLog.writeEvent(
+ 0x534e4554, "139287605", -1, "PIN code length mismatch");
+ return false;
+ }
+ service.logUserBondResponse(device, accept, source);
+ Log.i(
+ TAG,
+ "setPin: device=" + device + ", accept=" + accept + ", from " + getUidPidString());
+ return service.getNative()
+ .pinReply(getBytesFromAddress(device.getAddress()), accept, len, pinCode);
+ }
+
+ @Override
+ public boolean setPasskey(
+ BluetoothDevice device,
+ boolean accept,
+ int len,
+ byte[] passkey,
+ AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null
+ || !callerIsSystemOrActiveOrManagedUser(service, TAG, "setPasskey")
+ || !checkConnectPermissionForDataDelivery(service, source, TAG, "setPasskey")) {
+ return false;
+ }
+
+ DeviceProperties deviceProp = service.getRemoteDevices().getDeviceProperties(device);
+ if (deviceProp == null || !deviceProp.isBonding()) {
+ Log.e(TAG, "setPasskey: device=" + device + ", not bonding");
+ return false;
+ }
+ if (passkey.length != len) {
+ android.util.EventLog.writeEvent(
+ 0x534e4554, "139287605", -1, "Passkey length mismatch");
+ return false;
+ }
+ service.logUserBondResponse(device, accept, source);
+ Log.i(
+ TAG,
+ "setPasskey: device="
+ + device
+ + ", accept="
+ + accept
+ + ", from "
+ + getUidPidString());
+
+ return service.getNative()
+ .sspReply(
+ getBytesFromAddress(device.getAddress()),
+ AbstractionLayer.BT_SSP_VARIANT_PASSKEY_ENTRY,
+ accept,
+ Utils.byteArrayToInt(passkey));
+ }
+
+ @Override
+ public boolean setPairingConfirmation(
+ BluetoothDevice device, boolean accept, AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null
+ || !callerIsSystemOrActiveOrManagedUser(service, TAG, "setPairingConfirmation")
+ || !checkConnectPermissionForDataDelivery(
+ service, source, TAG, "setPairingConfirmation")) {
+ return false;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+
+ DeviceProperties deviceProp = service.getRemoteDevices().getDeviceProperties(device);
+ if (deviceProp == null || !deviceProp.isBonding()) {
+ Log.e(TAG, "setPairingConfirmation: device=" + device + ", not bonding");
+ return false;
+ }
+ service.logUserBondResponse(device, accept, source);
+ Log.i(
+ TAG,
+ "setPairingConfirmation: device="
+ + device
+ + ", accept="
+ + accept
+ + ", from "
+ + getUidPidString());
+
+ return service.getNative()
+ .sspReply(
+ getBytesFromAddress(device.getAddress()),
+ AbstractionLayer.BT_SSP_VARIANT_PASSKEY_CONFIRMATION,
+ accept,
+ 0);
+ }
+
+ @Override
+ public boolean getSilenceMode(BluetoothDevice device, AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null
+ || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getSilenceMode")
+ || !checkConnectPermissionForDataDelivery(service, source, TAG, "getSilenceMode")) {
+ return false;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.getSilenceDeviceManager().getSilenceMode(device);
+ }
+
+ @Override
+ public boolean setSilenceMode(
+ BluetoothDevice device, boolean silence, AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null
+ || !callerIsSystemOrActiveOrManagedUser(service, TAG, "setSilenceMode")
+ || !checkConnectPermissionForDataDelivery(service, source, TAG, "setSilenceMode")) {
+ return false;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ service.getSilenceDeviceManager().setSilenceMode(device, silence);
+ return true;
+ }
+
+ @Override
+ public int getPhonebookAccessPermission(BluetoothDevice device, AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null
+ || !callerIsSystemOrActiveOrManagedUser(
+ service, TAG, "getPhonebookAccessPermission")
+ || !checkConnectPermissionForDataDelivery(
+ service, source, TAG, "getPhonebookAccessPermission")) {
+ return BluetoothDevice.ACCESS_UNKNOWN;
+ }
+
+ return service.getPhonebookAccessPermission(device);
+ }
+
+ @Override
+ public boolean setPhonebookAccessPermission(
+ BluetoothDevice device, int value, AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null
+ || !callerIsSystemOrActiveOrManagedUser(
+ service, TAG, "setPhonebookAccessPermission")
+ || !checkConnectPermissionForDataDelivery(
+ service, source, TAG, "setPhonebookAccessPermission")) {
+ return false;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ service.setPhonebookAccessPermission(device, value);
+ return true;
+ }
+
+ @Override
+ public int getMessageAccessPermission(BluetoothDevice device, AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null
+ || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getMessageAccessPermission")
+ || !checkConnectPermissionForDataDelivery(
+ service, source, TAG, "getMessageAccessPermission")) {
+ return BluetoothDevice.ACCESS_UNKNOWN;
+ }
+
+ return service.getMessageAccessPermission(device);
+ }
+
+ @Override
+ public boolean setMessageAccessPermission(
+ BluetoothDevice device, int value, AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null
+ || !callerIsSystemOrActiveOrManagedUser(service, TAG, "setMessageAccessPermission")
+ || !checkConnectPermissionForDataDelivery(
+ service, source, TAG, "setMessageAccessPermission")) {
+ return false;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ service.setMessageAccessPermission(device, value);
+ return true;
+ }
+
+ @Override
+ public int getSimAccessPermission(BluetoothDevice device, AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null
+ || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getSimAccessPermission")
+ || !checkConnectPermissionForDataDelivery(
+ service, source, TAG, "getSimAccessPermission")) {
+ return BluetoothDevice.ACCESS_UNKNOWN;
+ }
+
+ return service.getSimAccessPermission(device);
+ }
+
+ @Override
+ public boolean setSimAccessPermission(
+ BluetoothDevice device, int value, AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null
+ || !callerIsSystemOrActiveOrManagedUser(service, TAG, "setSimAccessPermission")
+ || !checkConnectPermissionForDataDelivery(
+ service, source, TAG, "setSimAccessPermission")) {
+ return false;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ service.setSimAccessPermission(device, value);
+ return true;
+ }
+
+ @Override
+ public void logL2capcocServerConnection(
+ BluetoothDevice device,
+ int port,
+ boolean isSecured,
+ int result,
+ long socketCreationTimeMillis,
+ long socketCreationLatencyMillis,
+ long socketConnectionTimeMillis,
+ long timeoutMillis) {
+ AdapterService service = getService();
+ if (service == null) {
+ return;
+ }
+ service.logL2capcocServerConnection(
+ device,
+ port,
+ isSecured,
+ result,
+ socketCreationTimeMillis,
+ socketCreationLatencyMillis,
+ socketConnectionTimeMillis,
+ timeoutMillis,
+ Binder.getCallingUid());
+ }
+
+ @Override
+ public IBluetoothSocketManager getSocketManager() {
+ AdapterService service = getService();
+ if (service == null) {
+ return null;
+ }
+
+ return IBluetoothSocketManager.Stub.asInterface(service.getBluetoothSocketManagerBinder());
+ }
+
+ @Override
+ public void logL2capcocClientConnection(
+ BluetoothDevice device,
+ int port,
+ boolean isSecured,
+ int result,
+ long socketCreationTimeNanos,
+ long socketCreationLatencyNanos,
+ long socketConnectionTimeNanos) {
+ AdapterService service = getService();
+ if (service == null) {
+ return;
+ }
+ service.logL2capcocClientConnection(
+ device,
+ port,
+ isSecured,
+ result,
+ socketCreationTimeNanos,
+ socketCreationLatencyNanos,
+ socketConnectionTimeNanos,
+ Binder.getCallingUid());
+ }
+
+ @Override
+ public void logRfcommConnectionAttempt(
+ BluetoothDevice device,
+ boolean isSecured,
+ int resultCode,
+ long socketCreationTimeNanos,
+ boolean isSerialPort) {
+ AdapterService service = getService();
+ if (service == null) {
+ return;
+ }
+ service.logRfcommConnectionAttempt(
+ device,
+ isSecured,
+ resultCode,
+ socketCreationTimeNanos,
+ isSerialPort,
+ Binder.getCallingUid());
+ }
+
+ @Override
+ public boolean sdpSearch(BluetoothDevice device, ParcelUuid uuid, AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null
+ || !callerIsSystemOrActiveOrManagedUser(service, TAG, "sdpSearch")
+ || !checkConnectPermissionForDataDelivery(service, source, TAG, "sdpSearch")) {
+ return false;
+ }
+ return service.sdpSearch(device, uuid);
+ }
+
+ @Override
+ public int getBatteryLevel(BluetoothDevice device, AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null
+ || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getBatteryLevel")
+ || !checkConnectPermissionForDataDelivery(
+ service, source, TAG, "getBatteryLevel")) {
+ return BluetoothDevice.BATTERY_LEVEL_UNKNOWN;
+ }
+
+ DeviceProperties deviceProp = service.getRemoteDevices().getDeviceProperties(device);
+ if (deviceProp == null) {
+ return BluetoothDevice.BATTERY_LEVEL_UNKNOWN;
+ }
+ return deviceProp.getBatteryLevel();
+ }
+
+ @Override
+ public int getMaxConnectedAudioDevices(AttributionSource source) {
+ // don't check caller, may be called from system UI
+ AdapterService service = getService();
+ if (service == null
+ || !checkConnectPermissionForDataDelivery(
+ service, source, TAG, "getMaxConnectedAudioDevices")) {
+ return -1;
+ }
+
+ return service.getMaxConnectedAudioDevices();
+ }
+
+ @Override
+ public boolean factoryReset(AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null
+ || !checkConnectPermissionForDataDelivery(service, source, TAG, "factoryReset")) {
+ return false;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.factoryReset();
+ }
+
+ @Override
+ public void registerBluetoothConnectionCallback(
+ IBluetoothConnectionCallback callback, AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null
+ || !callerIsSystemOrActiveOrManagedUser(
+ service, TAG, "registerBluetoothConnectionCallback")
+ || !checkConnectPermissionForDataDelivery(
+ service, source, TAG, "registerBluetoothConnectionCallback")) {
+ return;
+ }
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ service.getBluetoothConnectionCallbacks().register(callback);
+ }
+
+ @Override
+ public void unregisterBluetoothConnectionCallback(
+ IBluetoothConnectionCallback callback, AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null
+ || !callerIsSystemOrActiveOrManagedUser(
+ service, TAG, "unregisterBluetoothConnectionCallback")
+ || !checkConnectPermissionForDataDelivery(
+ service, source, TAG, "unregisterBluetoothConnectionCallback")) {
+ return;
+ }
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ service.getBluetoothConnectionCallbacks().unregister(callback);
+ }
+
+ @Override
+ public void registerCallback(IBluetoothCallback callback, AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null
+ || !callerIsSystemOrActiveOrManagedUser(service, TAG, "registerCallback")
+ || !checkConnectPermissionForDataDelivery(
+ service, source, TAG, "registerCallback")) {
+ return;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ service.registerRemoteCallback(callback);
+ }
+
+ @Override
+ public void unregisterCallback(IBluetoothCallback callback, AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null
+ || !callerIsSystemOrActiveOrManagedUser(service, TAG, "unregisterCallback")
+ || !checkConnectPermissionForDataDelivery(
+ service, source, TAG, "unregisterCallback")) {
+ return;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ service.unregisterRemoteCallback(callback);
+ }
+
+ @Override
+ public boolean isMultiAdvertisementSupported() {
+ AdapterService service = getService();
+ if (service == null) {
+ return false;
+ }
+
+ int val = service.getAdapterProperties().getNumOfAdvertisementInstancesSupported();
+ return val >= MIN_ADVT_INSTANCES_FOR_MA;
+ }
+
+ /**
+ * This method has an associated binder cache. The invalidation methods must be changed if the
+ * logic behind this method changes.
+ */
+ @Override
+ public boolean isOffloadedFilteringSupported() {
+ AdapterService service = getService();
+ if (service == null) {
+ return false;
+ }
+
+ int val = service.getNumOfOffloadedScanFilterSupported();
+ return val >= MIN_OFFLOADED_FILTERS;
+ }
+
+ @Override
+ public boolean isOffloadedScanBatchingSupported() {
+ AdapterService service = getService();
+ if (service == null) {
+ return false;
+ }
+
+ int val = service.getOffloadedScanResultStorage();
+ return val >= MIN_OFFLOADED_SCAN_STORAGE_BYTES;
+ }
+
+ @Override
+ public boolean isLe2MPhySupported() {
+ AdapterService service = getService();
+ if (service == null) {
+ return false;
+ }
+
+ return service.isLe2MPhySupported();
+ }
+
+ @Override
+ public boolean isLeCodedPhySupported() {
+ AdapterService service = getService();
+ if (service == null) {
+ return false;
+ }
+
+ return service.isLeCodedPhySupported();
+ }
+
+ @Override
+ public boolean isLeExtendedAdvertisingSupported() {
+ AdapterService service = getService();
+ if (service == null) {
+ return false;
+ }
+
+ return service.isLeExtendedAdvertisingSupported();
+ }
+
+ @Override
+ public boolean isLePeriodicAdvertisingSupported() {
+ AdapterService service = getService();
+ if (service == null) {
+ return false;
+ }
+
+ return service.isLePeriodicAdvertisingSupported();
+ }
+
+ @Override
+ public int isLeAudioSupported() {
+ AdapterService service = getService();
+ if (service == null) {
+ return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED;
+ }
+
+ Set<Integer> supportedProfileServices =
+ Arrays.stream(Config.getSupportedProfiles()).boxed().collect(Collectors.toSet());
+ int[] leAudioUnicastProfiles = Config.getLeAudioUnicastProfiles();
+
+ if (Arrays.stream(leAudioUnicastProfiles).allMatch(supportedProfileServices::contains)) {
+ return BluetoothStatusCodes.FEATURE_SUPPORTED;
+ }
+
+ return BluetoothStatusCodes.FEATURE_NOT_SUPPORTED;
+ }
+
+ @Override
+ public int isLeAudioBroadcastSourceSupported() {
+ AdapterService service = getService();
+ if (service == null) {
+ return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED;
+ }
+
+ long supportBitMask = Config.getSupportedProfilesBitMask();
+ if ((supportBitMask & (1 << BluetoothProfile.LE_AUDIO_BROADCAST)) != 0) {
+ return BluetoothStatusCodes.FEATURE_SUPPORTED;
+ }
+
+ return BluetoothStatusCodes.FEATURE_NOT_SUPPORTED;
+ }
+
+ @Override
+ public int isLeAudioBroadcastAssistantSupported() {
+ AdapterService service = getService();
+ if (service == null) {
+ return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED;
+ }
+
+ int[] supportedProfileServices = Config.getSupportedProfiles();
+
+ if (Arrays.stream(supportedProfileServices)
+ .anyMatch(
+ profileId -> profileId == BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT)) {
+ return BluetoothStatusCodes.FEATURE_SUPPORTED;
+ }
+
+ return BluetoothStatusCodes.FEATURE_NOT_SUPPORTED;
+ }
+
+ @Override
+ public int isDistanceMeasurementSupported(AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null) {
+ return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED;
+ } else if (!callerIsSystemOrActiveOrManagedUser(
+ service, TAG, "isDistanceMeasurementSupported")) {
+ return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ALLOWED;
+ } else if (!checkConnectPermissionForDataDelivery(
+ service, source, TAG, "isDistanceMeasurementSupported")) {
+ return BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION;
+ }
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return BluetoothStatusCodes.FEATURE_SUPPORTED;
+ }
+
+ @Override
+ public int getLeMaximumAdvertisingDataLength() {
+ AdapterService service = getService();
+ if (service == null) {
+ return 0;
+ }
+
+ return service.getLeMaximumAdvertisingDataLength();
+ }
+
+ @Override
+ public boolean isActivityAndEnergyReportingSupported() {
+ AdapterService service = getService();
+ if (service == null) {
+ return false;
+ }
+
+ return service.getAdapterProperties().isActivityAndEnergyReportingSupported();
+ }
+
+ @Override
+ public BluetoothActivityEnergyInfo reportActivityInfo(AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null
+ || !checkConnectPermissionForDataDelivery(
+ service, source, TAG, "reportActivityInfo")) {
+ return null;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.reportActivityInfo();
+ }
+
+ @Override
+ public boolean registerMetadataListener(
+ IBluetoothMetadataListener listener, BluetoothDevice device, AttributionSource source) {
+ requireNonNull(device);
+ requireNonNull(listener);
+ AdapterService service = getService();
+ if (service == null
+ || !callerIsSystemOrActiveOrManagedUser(service, TAG, "registerMetadataListener")
+ || !checkConnectPermissionForDataDelivery(
+ service, source, TAG, "registerMetadataListener")) {
+ return false;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ service.getHandler()
+ .post(
+ () ->
+ service.getMetadataListeners()
+ .computeIfAbsent(device, k -> new RemoteCallbackList())
+ .register(listener));
+ return true;
+ }
+
+ @Override
+ public boolean unregisterMetadataListener(
+ IBluetoothMetadataListener listener, BluetoothDevice device, AttributionSource source) {
+ requireNonNull(device);
+ requireNonNull(listener);
+ AdapterService service = getService();
+ if (service == null
+ || !callerIsSystemOrActiveOrManagedUser(service, TAG, "unregisterMetadataListener")
+ || !checkConnectPermissionForDataDelivery(
+ service, source, TAG, "unregisterMetadataListener")) {
+ return false;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ service.getHandler()
+ .post(
+ () ->
+ service.getMetadataListeners()
+ .computeIfPresent(
+ device,
+ (k, v) -> {
+ v.unregister(listener);
+ if (v.getRegisteredCallbackCount() == 0) {
+ return null;
+ }
+ return v;
+ }));
+ return true;
+ }
+
+ @Override
+ public boolean setMetadata(
+ BluetoothDevice device, int key, byte[] value, AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null
+ || !callerIsSystemOrActiveOrManagedUser(service, TAG, "setMetadata")
+ || !checkConnectPermissionForDataDelivery(service, source, TAG, "setMetadata")) {
+ return false;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.setMetadata(device, key, value);
+ }
+
+ @Override
+ public byte[] getMetadata(BluetoothDevice device, int key, AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null
+ || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getMetadata")
+ || !checkConnectPermissionForDataDelivery(service, source, TAG, "getMetadata")) {
+ return null;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.getMetadata(device, key);
+ }
+
+ @Override
+ public int isRequestAudioPolicyAsSinkSupported(
+ BluetoothDevice device, AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null
+ || !callerIsSystemOrActiveOrManagedUser(
+ service, TAG, "isRequestAudioPolicyAsSinkSupported")
+ || !checkConnectPermissionForDataDelivery(
+ service, source, TAG, "isRequestAudioPolicyAsSinkSupported")) {
+ return BluetoothStatusCodes.FEATURE_NOT_CONFIGURED;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.isRequestAudioPolicyAsSinkSupported(device);
+ }
+
+ @Override
+ public int requestAudioPolicyAsSink(
+ BluetoothDevice device, BluetoothSinkAudioPolicy policies, AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null) {
+ return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED;
+ } else if (!callerIsSystemOrActiveOrManagedUser(service, TAG, "requestAudioPolicyAsSink")) {
+ return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ALLOWED;
+ } else if (!checkConnectPermissionForDataDelivery(
+ service, source, TAG, "requestAudioPolicyAsSink")) {
+ return BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.requestAudioPolicyAsSink(device, policies);
+ }
+
+ @Override
+ public BluetoothSinkAudioPolicy getRequestedAudioPolicyAsSink(
+ BluetoothDevice device, AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null
+ || !callerIsSystemOrActiveOrManagedUser(
+ service, TAG, "getRequestedAudioPolicyAsSink")
+ || !checkConnectPermissionForDataDelivery(
+ service, source, TAG, "getRequestedAudioPolicyAsSink")) {
+ return null;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.getRequestedAudioPolicyAsSink(device);
+ }
+
+ @Override
+ public void requestActivityInfo(
+ IBluetoothActivityEnergyInfoListener listener, AttributionSource source) {
+ BluetoothActivityEnergyInfo info = reportActivityInfo(source);
+ try {
+ listener.onBluetoothActivityEnergyInfoAvailable(info);
+ } catch (RemoteException e) {
+ Log.e(TAG, "onBluetoothActivityEnergyInfo: RemoteException", e);
+ }
+ }
+
+ @Override
+ public void bleOnToOn(AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "bleOnToOn")) {
+ return;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ service.bleOnToOn();
+ }
+
+ @Override
+ public void bleOnToOff(AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "bleOnToOff")) {
+ return;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ service.bleOnToOff();
+ }
+
+ @Override
+ public void dump(FileDescriptor fd, String[] args) {
+ PrintWriter writer = new PrintWriter(new FileOutputStream(fd));
+ AdapterService service = getService();
+ if (service == null) {
+ return;
+ }
+
+ service.enforceCallingOrSelfPermission(DUMP, null);
+ service.dump(fd, writer, args);
+ writer.close();
+ }
+
+ @Override
+ public boolean allowLowLatencyAudio(boolean allowed, BluetoothDevice device) {
+ AdapterService service = getService();
+ if (service == null
+ || !callerIsSystemOrActiveOrManagedUser(service, TAG, "allowLowLatencyAudio")
+ || !checkConnectPermissionForDataDelivery(
+ service,
+ Utils.getCallingAttributionSource(service),
+ TAG,
+ "allowLowLatencyAudio")) {
+ return false;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.allowLowLatencyAudio(allowed, device);
+ }
+
+ @Override
+ public int startRfcommListener(
+ String name, ParcelUuid uuid, PendingIntent pendingIntent, AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null
+ || !callerIsSystemOrActiveOrManagedUser(service, TAG, "startRfcommListener")
+ || !checkConnectPermissionForDataDelivery(
+ service, source, TAG, "startRfcommListener")) {
+ return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ALLOWED;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.startRfcommListener(name, uuid, pendingIntent, source);
+ }
+
+ @Override
+ public int stopRfcommListener(ParcelUuid uuid, AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null
+ || !callerIsSystemOrActiveOrManagedUser(service, TAG, "stopRfcommListener")
+ || !checkConnectPermissionForDataDelivery(
+ service, source, TAG, "stopRfcommListener")) {
+ return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ALLOWED;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.stopRfcommListener(uuid, source);
+ }
+
+ @Override
+ public IncomingRfcommSocketInfo retrievePendingSocketForServiceRecord(
+ ParcelUuid uuid, AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null
+ || !callerIsSystemOrActiveOrManagedUser(
+ service, TAG, "retrievePendingSocketForServiceRecord")
+ || !checkConnectPermissionForDataDelivery(
+ service, source, TAG, "retrievePendingSocketForServiceRecord")) {
+ return null;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.retrievePendingSocketForServiceRecord(uuid, source);
+ }
+
+ @Override
+ public void setForegroundUserId(int userId, AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null
+ || !checkConnectPermissionForDataDelivery(
+ service,
+ Utils.getCallingAttributionSource(mService),
+ TAG,
+ "setForegroundUserId")) {
+ return;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ Utils.setForegroundUserId(userId);
+ }
+
+ @Override
+ public int setPreferredAudioProfiles(
+ BluetoothDevice device, Bundle modeToProfileBundle, AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null) {
+ return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED;
+ }
+ if (!callerIsSystemOrActiveOrManagedUser(service, TAG, "setPreferredAudioProfiles")) {
+ return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ALLOWED;
+ }
+ requireNonNull(device);
+ requireNonNull(modeToProfileBundle);
+ if (!BluetoothAdapter.checkBluetoothAddress(device.getAddress())) {
+ throw new IllegalArgumentException("device cannot have an invalid address");
+ }
+ if (service.getBondState(device) != BluetoothDevice.BOND_BONDED) {
+ return BluetoothStatusCodes.ERROR_DEVICE_NOT_BONDED;
+ }
+ if (!checkConnectPermissionForDataDelivery(
+ service, source, TAG, "setPreferredAudioProfiles")) {
+ return BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.setPreferredAudioProfiles(device, modeToProfileBundle);
+ }
+
+ @Override
+ public Bundle getPreferredAudioProfiles(BluetoothDevice device, AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null) {
+ return Bundle.EMPTY;
+ }
+ if (!callerIsSystemOrActiveOrManagedUser(service, TAG, "getPreferredAudioProfiles")) {
+ return Bundle.EMPTY;
+ }
+ requireNonNull(device);
+ if (!BluetoothAdapter.checkBluetoothAddress(device.getAddress())) {
+ throw new IllegalArgumentException("device cannot have an invalid address");
+ }
+ if (service.getBondState(device) != BluetoothDevice.BOND_BONDED) {
+ return Bundle.EMPTY;
+ }
+ if (!checkConnectPermissionForDataDelivery(
+ service, source, TAG, "getPreferredAudioProfiles")) {
+ return Bundle.EMPTY;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.getPreferredAudioProfiles(device);
+ }
+
+ @Override
+ public int notifyActiveDeviceChangeApplied(BluetoothDevice device, AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null) {
+ return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED;
+ }
+ if (!callerIsSystem(TAG, "notifyActiveDeviceChangeApplied")) {
+ return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ALLOWED;
+ }
+ requireNonNull(device);
+ if (!BluetoothAdapter.checkBluetoothAddress(device.getAddress())) {
+ throw new IllegalArgumentException("device cannot have an invalid address");
+ }
+ if (service.getBondState(device) != BluetoothDevice.BOND_BONDED) {
+ return BluetoothStatusCodes.ERROR_DEVICE_NOT_BONDED;
+ }
+ if (!checkConnectPermissionForDataDelivery(
+ service, source, TAG, "notifyActiveDeviceChangeApplied")) {
+ return BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.notifyActiveDeviceChangeApplied(device);
+ }
+
+ @Override
+ public int isDualModeAudioEnabled(AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null) {
+ return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED;
+ }
+ if (!checkConnectPermissionForDataDelivery(
+ service, source, TAG, "isDualModeAudioEnabled")) {
+ return BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ if (!Utils.isDualModeAudioEnabled()) {
+ return BluetoothStatusCodes.FEATURE_NOT_SUPPORTED;
+ }
+
+ return BluetoothStatusCodes.SUCCESS;
+ }
+
+ @Override
+ public int registerPreferredAudioProfilesChangedCallback(
+ IBluetoothPreferredAudioProfilesCallback callback, AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null) {
+ return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED;
+ }
+ if (!callerIsSystemOrActiveOrManagedUser(
+ service, TAG, "registerPreferredAudioProfilesChangedCallback")) {
+ return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ALLOWED;
+ }
+ requireNonNull(callback);
+ if (!checkConnectPermissionForDataDelivery(
+ service, source, TAG, "registerPreferredAudioProfilesChangedCallback")) {
+ return BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ // If LE only mode is enabled, the dual mode audio feature is disabled
+ if (!Utils.isDualModeAudioEnabled()) {
+ return BluetoothStatusCodes.FEATURE_NOT_SUPPORTED;
+ }
+
+ service.getPreferredAudioProfilesCallbacks().register(callback);
+ return BluetoothStatusCodes.SUCCESS;
+ }
+
+ @Override
+ public int unregisterPreferredAudioProfilesChangedCallback(
+ IBluetoothPreferredAudioProfilesCallback callback, AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null) {
+ return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED;
+ }
+ if (!callerIsSystemOrActiveOrManagedUser(
+ service, TAG, "unregisterPreferredAudioProfilesChangedCallback")) {
+ return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ALLOWED;
+ }
+ requireNonNull(callback);
+ if (!checkConnectPermissionForDataDelivery(
+ service, source, TAG, "unregisterPreferredAudioProfilesChangedCallback")) {
+ return BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ if (!service.getPreferredAudioProfilesCallbacks().unregister(callback)) {
+ Log.e(
+ TAG,
+ "unregisterPreferredAudioProfilesChangedCallback: callback was never "
+ + "registered");
+ return BluetoothStatusCodes.ERROR_CALLBACK_NOT_REGISTERED;
+ }
+ return BluetoothStatusCodes.SUCCESS;
+ }
+
+ @Override
+ public int registerBluetoothQualityReportReadyCallback(
+ IBluetoothQualityReportReadyCallback callback, AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null) {
+ return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED;
+ }
+ if (!callerIsSystemOrActiveOrManagedUser(
+ service, TAG, "registerBluetoothQualityReportReadyCallback")) {
+ return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ALLOWED;
+ }
+ requireNonNull(callback);
+ if (!checkConnectPermissionForDataDelivery(
+ service, source, TAG, "registerBluetoothQualityReportReadyCallback")) {
+ return BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ service.getBluetoothQualityReportReadyCallbacks().register(callback);
+ return BluetoothStatusCodes.SUCCESS;
+ }
+
+ @Override
+ public int unregisterBluetoothQualityReportReadyCallback(
+ IBluetoothQualityReportReadyCallback callback, AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null) {
+ return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED;
+ }
+ if (!callerIsSystemOrActiveOrManagedUser(
+ service, TAG, "unregisterBluetoothQualityReportReadyCallback")) {
+ return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ALLOWED;
+ }
+ requireNonNull(callback);
+ if (!checkConnectPermissionForDataDelivery(
+ service, source, TAG, "unregisterBluetoothQualityReportReadyCallback")) {
+ return BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ if (!service.getBluetoothQualityReportReadyCallbacks().unregister(callback)) {
+ Log.e(
+ TAG,
+ "unregisterBluetoothQualityReportReadyCallback: callback was never registered");
+ return BluetoothStatusCodes.ERROR_CALLBACK_NOT_REGISTERED;
+ }
+ return BluetoothStatusCodes.SUCCESS;
+ }
+
+ @Override
+ public void registerHciVendorSpecificCallback(
+ IBluetoothHciVendorSpecificCallback callback, int[] eventCodes) {
+ AdapterService service = getService();
+ if (service == null) {
+ return;
+ }
+ if (!callerIsSystemOrActiveOrManagedUser(
+ service, TAG, "registerHciVendorSpecificCallback")) {
+ throw new SecurityException("not allowed");
+ }
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ requireNonNull(callback);
+ requireNonNull(eventCodes);
+
+ Set<Integer> eventCodesSet = Arrays.stream(eventCodes).boxed().collect(Collectors.toSet());
+ if (eventCodesSet.stream()
+ .anyMatch((n) -> (n < 0) || (n >= 0x52 && n < 0x60) || (n > 0xff))) {
+ throw new IllegalArgumentException("invalid vendor-specific event code");
+ }
+
+ service.getBluetoothHciVendorSpecificDispatcher().register(callback, eventCodesSet);
+ }
+
+ @Override
+ public void unregisterHciVendorSpecificCallback(IBluetoothHciVendorSpecificCallback callback) {
+ AdapterService service = getService();
+ if (service == null) {
+ return;
+ }
+ if (!callerIsSystemOrActiveOrManagedUser(
+ service, TAG, "unregisterHciVendorSpecificCallback")) {
+ throw new SecurityException("not allowed");
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ requireNonNull(callback);
+ service.getBluetoothHciVendorSpecificDispatcher().unregister(callback);
+ }
+
+ @Override
+ public void sendHciVendorSpecificCommand(
+ int ocf, byte[] parameters, IBluetoothHciVendorSpecificCallback callback) {
+ AdapterService service = getService();
+ if (service == null) {
+ return;
+ }
+ if (!callerIsSystemOrActiveOrManagedUser(service, TAG, "sendHciVendorSpecificCommand")) {
+ throw new SecurityException("not allowed");
+ }
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+
+ // Open this no-op android command for test purpose
+ int getVendorCapabilitiesOcf = 0x153;
+ if (ocf < 0
+ || (ocf >= 0x150 && ocf < 0x160 && ocf != getVendorCapabilitiesOcf)
+ || (ocf > 0x3ff)) {
+ throw new IllegalArgumentException("invalid vendor-specific event code");
+ }
+ requireNonNull(parameters);
+ if (parameters.length > 255) {
+ throw new IllegalArgumentException("Parameters size is too big");
+ }
+
+ Optional<byte[]> cookie =
+ service.getBluetoothHciVendorSpecificDispatcher().getRegisteredCookie(callback);
+ if (!cookie.isPresent()) {
+ Log.e(TAG, "send command without registered callback");
+ throw new IllegalStateException("callback not registered");
+ }
+
+ service.getBluetoothHciVendorSpecificNativeInterface()
+ .sendCommand(ocf, parameters, cookie.get());
+ }
+
+ @Override
+ public int getOffloadedTransportDiscoveryDataScanSupported(AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null
+ || !callerIsSystemOrActiveOrManagedUser(
+ service, TAG, "getOffloadedTransportDiscoveryDataScanSupported")
+ || !checkScanPermissionForDataDelivery(
+ service, source, TAG, "getOffloadedTransportDiscoveryDataScanSupported")) {
+ return BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_SCAN_PERMISSION;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.getOffloadedTransportDiscoveryDataScanSupported();
+ }
+
+ @Override
+ public boolean isMediaProfileConnected(AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null
+ || !checkConnectPermissionForDataDelivery(
+ service, source, TAG, "isMediaProfileConnected")) {
+ return false;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.isMediaProfileConnected();
+ }
+
+ @Override
+ public IBinder getBluetoothGatt() {
+ AdapterService service = getService();
+ return service == null ? null : service.getBluetoothGatt();
+ }
+
+ @Override
+ public IBinder getBluetoothScan() {
+ AdapterService service = getService();
+ return service == null ? null : service.getBluetoothScan();
+ }
+
+ @Override
+ public void unregAllGattClient(AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null) {
+ return;
+ }
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ service.unregAllGattClient(source);
+ }
+
+ @Override
+ public IBinder getProfile(int profileId) {
+ AdapterService service = getService();
+ if (service == null) {
+ return null;
+ }
+
+ return service.getProfile(profileId);
+ }
+
+ @Override
+ public int setActiveAudioDevicePolicy(
+ BluetoothDevice device, int activeAudioDevicePolicy, AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null) {
+ return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED;
+ }
+ if (!callerIsSystemOrActiveOrManagedUser(service, TAG, "setActiveAudioDevicePolicy")) {
+ return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ALLOWED;
+ }
+ if (!BluetoothAdapter.checkBluetoothAddress(device.getAddress())) {
+ throw new IllegalArgumentException("device cannot have an invalid address");
+ }
+ if (!checkConnectPermissionForDataDelivery(
+ service, source, TAG, "setActiveAudioDevicePolicy")) {
+ return BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.getDatabaseManager()
+ .setActiveAudioDevicePolicy(device, activeAudioDevicePolicy);
+ }
+
+ @Override
+ public int getActiveAudioDevicePolicy(BluetoothDevice device, AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null) {
+ return BluetoothDevice.ACTIVE_AUDIO_DEVICE_POLICY_DEFAULT;
+ }
+ if (!callerIsSystemOrActiveOrManagedUser(service, TAG, "getActiveAudioDevicePolicy")) {
+ throw new IllegalStateException(
+ "Caller is not the system or part of the active/managed user");
+ }
+ if (!BluetoothAdapter.checkBluetoothAddress(device.getAddress())) {
+ throw new IllegalArgumentException("device cannot have an invalid address");
+ }
+ if (!checkConnectPermissionForDataDelivery(
+ service, source, TAG, "getActiveAudioDevicePolicy")) {
+ return BluetoothDevice.ACTIVE_AUDIO_DEVICE_POLICY_DEFAULT;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.getDatabaseManager().getActiveAudioDevicePolicy(device);
+ }
+
+ @Override
+ public int setMicrophonePreferredForCalls(
+ BluetoothDevice device, boolean enabled, AttributionSource source) {
+ requireNonNull(device);
+ AdapterService service = getService();
+ if (service == null) {
+ return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED;
+ }
+ if (!callerIsSystemOrActiveOrManagedUser(service, TAG, "setMicrophonePreferredForCalls")) {
+ return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ALLOWED;
+ }
+ if (!BluetoothAdapter.checkBluetoothAddress(device.getAddress())) {
+ throw new IllegalArgumentException("device cannot have an invalid address");
+ }
+ if (!checkConnectPermissionForDataDelivery(
+ service, source, TAG, "setMicrophonePreferredForCalls")) {
+ return BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.getDatabaseManager().setMicrophonePreferredForCalls(device, enabled);
+ }
+
+ @Override
+ public boolean isMicrophonePreferredForCalls(BluetoothDevice device, AttributionSource source) {
+ requireNonNull(device);
+ AdapterService service = getService();
+ if (service == null) {
+ return true;
+ }
+ if (!callerIsSystemOrActiveOrManagedUser(service, TAG, "isMicrophonePreferredForCalls")) {
+ throw new IllegalStateException(
+ "Caller is not the system or part of the active/managed user");
+ }
+ if (!BluetoothAdapter.checkBluetoothAddress(device.getAddress())) {
+ throw new IllegalArgumentException("device cannot have an invalid address");
+ }
+ if (!checkConnectPermissionForDataDelivery(
+ service, source, TAG, "isMicrophonePreferredForCalls")) {
+ return true;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.getDatabaseManager().isMicrophonePreferredForCalls(device);
+ }
+
+ @Override
+ public boolean isLeCocSocketOffloadSupported(AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null) {
+ return false;
+ }
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.isLeCocSocketOffloadSupported();
+ }
+
+ @Override
+ public boolean isRfcommSocketOffloadSupported(AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null) {
+ return false;
+ }
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.isRfcommSocketOffloadSupported();
+ }
+
+ @Override
+ public IBinder getBluetoothAdvertise() {
+ AdapterService service = getService();
+ return service == null ? null : service.getBluetoothAdvertise();
+ }
+
+ @Override
+ public IBinder getDistanceMeasurement() {
+ AdapterService service = getService();
+ return service == null ? null : service.getDistanceMeasurement();
+ }
+
+ @Override
+ public int getKeyMissingCount(BluetoothDevice device, AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null) {
+ return -1;
+ }
+ if (!callerIsSystemOrActiveOrManagedUser(service, TAG, "getKeyMissingCount")) {
+ throw new IllegalStateException(
+ "Caller is not the system or part of the active/managed user");
+ }
+ if (!BluetoothAdapter.checkBluetoothAddress(device.getAddress())) {
+ throw new IllegalArgumentException("device cannot have an invalid address");
+ }
+ if (!checkConnectPermissionForDataDelivery(service, source, TAG, "getKeyMissingCount")) {
+ return -1;
+ }
+
+ return service.getDatabaseManager().getKeyMissingCount(device);
+ }
+}
diff --git a/android/app/src/com/android/bluetooth/btservice/AdapterSuspend.java b/android/app/src/com/android/bluetooth/btservice/AdapterSuspend.java
index d49865e1ce..e7e9e870b8 100644
--- a/android/app/src/com/android/bluetooth/btservice/AdapterSuspend.java
+++ b/android/app/src/com/android/bluetooth/btservice/AdapterSuspend.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 The Android Open Source Project
+ * Copyright (C) 2024 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.
diff --git a/android/app/src/com/android/bluetooth/btservice/BluetoothAdapterProxy.java b/android/app/src/com/android/bluetooth/btservice/BluetoothAdapterProxy.java
index b7a67a7e66..20d3f5577f 100644
--- a/android/app/src/com/android/bluetooth/btservice/BluetoothAdapterProxy.java
+++ b/android/app/src/com/android/bluetooth/btservice/BluetoothAdapterProxy.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/src/com/android/bluetooth/btservice/BluetoothHciVendorSpecificDispatcher.java b/android/app/src/com/android/bluetooth/btservice/BluetoothHciVendorSpecificDispatcher.java
index 1635742b76..a767c6a3c9 100644
--- a/android/app/src/com/android/bluetooth/btservice/BluetoothHciVendorSpecificDispatcher.java
+++ b/android/app/src/com/android/bluetooth/btservice/BluetoothHciVendorSpecificDispatcher.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 The Android Open Source Project
+ * Copyright (C) 2024 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.
diff --git a/android/app/src/com/android/bluetooth/btservice/BluetoothHciVendorSpecificNativeInterface.java b/android/app/src/com/android/bluetooth/btservice/BluetoothHciVendorSpecificNativeInterface.java
index 010b1e6ce5..58c55978a7 100644
--- a/android/app/src/com/android/bluetooth/btservice/BluetoothHciVendorSpecificNativeInterface.java
+++ b/android/app/src/com/android/bluetooth/btservice/BluetoothHciVendorSpecificNativeInterface.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 The Android Open Source Project
+ * Copyright (C) 2024 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.
diff --git a/android/app/src/com/android/bluetooth/btservice/BluetoothQualityReportNativeInterface.java b/android/app/src/com/android/bluetooth/btservice/BluetoothQualityReportNativeInterface.java
index 2f4c03c17c..88f6e13638 100644
--- a/android/app/src/com/android/bluetooth/btservice/BluetoothQualityReportNativeInterface.java
+++ b/android/app/src/com/android/bluetooth/btservice/BluetoothQualityReportNativeInterface.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 The Android Open Source Project
+ * Copyright (C) 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.
diff --git a/android/app/src/com/android/bluetooth/btservice/BluetoothSocketManagerBinder.java b/android/app/src/com/android/bluetooth/btservice/BluetoothSocketManagerBinder.java
index c9b1c82473..f9dcbe8017 100644
--- a/android/app/src/com/android/bluetooth/btservice/BluetoothSocketManagerBinder.java
+++ b/android/app/src/com/android/bluetooth/btservice/BluetoothSocketManagerBinder.java
@@ -286,7 +286,7 @@ class BluetoothSocketManagerBinder extends IBluetoothSocketManager.Stub {
|| !Utils.callerIsSystemOrActiveOrManagedUser(
service, TAG, "getL2capLocalChannelId")
|| !Utils.checkConnectPermissionForDataDelivery(
- service, source, "BluetoothSocketManagerBinder getL2capLocalChannelId")) {
+ service, source, TAG, "getL2capLocalChannelId")) {
return INVALID_CID;
}
service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
@@ -300,7 +300,7 @@ class BluetoothSocketManagerBinder extends IBluetoothSocketManager.Stub {
|| !Utils.callerIsSystemOrActiveOrManagedUser(
service, TAG, "getL2capRemoteChannelId")
|| !Utils.checkConnectPermissionForDataDelivery(
- service, source, "BluetoothSocketManagerBinder getL2capRemoteChannelId")) {
+ service, source, TAG, "getL2capRemoteChannelId")) {
return INVALID_CID;
}
service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
diff --git a/android/app/src/com/android/bluetooth/btservice/Config.java b/android/app/src/com/android/bluetooth/btservice/Config.java
index 1cac6b8c8b..a0e9d3fab9 100644
--- a/android/app/src/com/android/bluetooth/btservice/Config.java
+++ b/android/app/src/com/android/bluetooth/btservice/Config.java
@@ -48,7 +48,6 @@ import com.android.bluetooth.pbapclient.PbapClientService;
import com.android.bluetooth.sap.SapService;
import com.android.bluetooth.tbs.TbsService;
import com.android.bluetooth.vc.VolumeControlService;
-import com.android.internal.annotations.VisibleForTesting;
import java.util.Arrays;
@@ -126,9 +125,11 @@ public class Config {
LeAudioService.isBroadcastEnabled(), BluetoothProfile.LE_AUDIO_BROADCAST),
};
- /** A test function to allow for dynamic enabled */
- @VisibleForTesting
- public static void setProfileEnabled(int profileId, boolean enabled) {
+ /**
+ * A test function to allow for dynamic enabled TODO: b/402559309 Remove non test usages
+ * (LeAudio)
+ */
+ static void setProfileEnabled(int profileId, boolean enabled) {
for (ProfileConfig profile : PROFILE_SERVICES_AND_FLAGS) {
if (profileId == profile.mProfileId) {
profile.mSupported = enabled;
diff --git a/android/app/src/com/android/bluetooth/btservice/DiscoveringPackage.java b/android/app/src/com/android/bluetooth/btservice/DiscoveringPackage.java
index 02723ef984..1e96abce86 100644
--- a/android/app/src/com/android/bluetooth/btservice/DiscoveringPackage.java
+++ b/android/app/src/com/android/bluetooth/btservice/DiscoveringPackage.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/android/app/src/com/android/bluetooth/btservice/MetricsLogger.java b/android/app/src/com/android/bluetooth/btservice/MetricsLogger.java
index 5d490e3a1a..f59e69a42d 100644
--- a/android/app/src/com/android/bluetooth/btservice/MetricsLogger.java
+++ b/android/app/src/com/android/bluetooth/btservice/MetricsLogger.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 The Android Open Source Project
+ * Copyright (C) 2018 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.
@@ -37,6 +37,12 @@ import static com.android.bluetooth.BluetoothStatsLog.BLUETOOTH_CROSS_LAYER_EVEN
import static com.android.bluetooth.BluetoothStatsLog.BLUETOOTH_CROSS_LAYER_EVENT_REPORTED__EVENT_TYPE__PROFILE_CONNECTION_VOLUME_CONTROL;
import static com.android.bluetooth.BluetoothStatsLog.BLUETOOTH_CROSS_LAYER_EVENT_REPORTED__STATE__STATE_BONDED;
import static com.android.bluetooth.BluetoothStatsLog.BLUETOOTH_CROSS_LAYER_EVENT_REPORTED__STATE__STATE_NONE;
+import static com.android.bluetooth.BluetoothStatsLog.HEARING_DEVICE_ACTIVE_EVENT_REPORTED__DEVICE_TYPE__ASHA;
+import static com.android.bluetooth.BluetoothStatsLog.HEARING_DEVICE_ACTIVE_EVENT_REPORTED__DEVICE_TYPE__CLASSIC;
+import static com.android.bluetooth.BluetoothStatsLog.HEARING_DEVICE_ACTIVE_EVENT_REPORTED__DEVICE_TYPE__LE_AUDIO;
+import static com.android.bluetooth.BluetoothStatsLog.HEARING_DEVICE_ACTIVE_EVENT_REPORTED__TIME_PERIOD__DAY;
+import static com.android.bluetooth.BluetoothStatsLog.HEARING_DEVICE_ACTIVE_EVENT_REPORTED__TIME_PERIOD__MONTH;
+import static com.android.bluetooth.BluetoothStatsLog.HEARING_DEVICE_ACTIVE_EVENT_REPORTED__TIME_PERIOD__WEEK;
import static com.android.bluetooth.BtRestrictedStatsLog.RESTRICTED_BLUETOOTH_DEVICE_NAME_REPORTED;
import android.app.AlarmManager;
@@ -45,6 +51,7 @@ import android.bluetooth.BluetoothA2dpSink;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothAvrcpController;
import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothHapClient;
import android.bluetooth.BluetoothHeadset;
import android.bluetooth.BluetoothHeadsetClient;
import android.bluetooth.BluetoothHearingAid;
@@ -60,20 +67,19 @@ import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothProtoEnums;
import android.bluetooth.BluetoothSap;
import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Build;
import android.os.SystemClock;
+import android.provider.Settings;
import android.util.Log;
import android.util.proto.ProtoOutputStream;
import androidx.annotation.RequiresApi;
-import com.android.bluetooth.BluetoothMetricsProto.BluetoothLog;
import com.android.bluetooth.BluetoothMetricsProto.BluetoothRemoteDeviceInformation;
-import com.android.bluetooth.BluetoothMetricsProto.ProfileConnectionStats;
-import com.android.bluetooth.BluetoothMetricsProto.ProfileId;
import com.android.bluetooth.BluetoothStatsLog;
import com.android.bluetooth.BtRestrictedStatsLog;
import com.android.bluetooth.Utils;
@@ -90,11 +96,14 @@ import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
+import java.util.function.BiPredicate;
/** Class of Bluetooth Metrics */
public class MetricsLogger {
@@ -112,8 +121,6 @@ public class MetricsLogger {
private static final long BLUETOOTH_COUNTER_METRICS_ACTION_DURATION_MILLIS = 6L * 3600L * 1000L;
private static final int MAX_WORDS_ALLOWED_IN_DEVICE_NAME = 7;
- private static final HashMap<ProfileId, Integer> sProfileConnectionCounts = new HashMap<>();
-
HashMap<Integer, Long> mCounters = new HashMap<>();
private static volatile MetricsLogger sInstance = null;
private AdapterService mAdapterService = null;
@@ -278,6 +285,7 @@ public class MetricsLogger {
filter.addAction(BluetoothPbap.ACTION_CONNECTION_STATE_CHANGED);
filter.addAction(BluetoothPbapClient.ACTION_CONNECTION_STATE_CHANGED);
filter.addAction(BluetoothSap.ACTION_CONNECTION_STATE_CHANGED);
+ filter.addAction(BluetoothHapClient.ACTION_HAP_CONNECTION_STATE_CHANGED);
mAdapterService.registerReceiver(mReceiver, filter);
}
@@ -290,9 +298,18 @@ public class MetricsLogger {
Log.w(TAG, "Received intent with null action");
return;
}
+ BluetoothDevice device =
+ intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
+ int state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, -1);
switch (action) {
case BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED:
logConnectionStateChanges(BluetoothProfile.A2DP, intent);
+ if (state == BluetoothProfile.STATE_CONNECTED
+ && isMedicalDevice(device)) {
+ updateHearingDeviceActiveTime(
+ device,
+ HEARING_DEVICE_ACTIVE_EVENT_REPORTED__DEVICE_TYPE__CLASSIC);
+ }
break;
case BluetoothA2dpSink.ACTION_CONNECTION_STATE_CHANGED:
logConnectionStateChanges(BluetoothProfile.A2DP_SINK, intent);
@@ -302,12 +319,23 @@ public class MetricsLogger {
break;
case BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED:
logConnectionStateChanges(BluetoothProfile.HEADSET, intent);
+ if (state == BluetoothProfile.STATE_CONNECTED
+ && isMedicalDevice(device)) {
+ updateHearingDeviceActiveTime(
+ device,
+ HEARING_DEVICE_ACTIVE_EVENT_REPORTED__DEVICE_TYPE__CLASSIC);
+ }
break;
case BluetoothHeadsetClient.ACTION_CONNECTION_STATE_CHANGED:
logConnectionStateChanges(BluetoothProfile.HEADSET_CLIENT, intent);
break;
case BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED:
logConnectionStateChanges(BluetoothProfile.HEARING_AID, intent);
+ if (state == BluetoothProfile.STATE_CONNECTED) {
+ updateHearingDeviceActiveTime(
+ device,
+ HEARING_DEVICE_ACTIVE_EVENT_REPORTED__DEVICE_TYPE__ASHA);
+ }
break;
case BluetoothHidDevice.ACTION_CONNECTION_STATE_CHANGED:
logConnectionStateChanges(BluetoothProfile.HID_DEVICE, intent);
@@ -336,6 +364,14 @@ public class MetricsLogger {
case BluetoothSap.ACTION_CONNECTION_STATE_CHANGED:
logConnectionStateChanges(BluetoothProfile.SAP, intent);
break;
+ case BluetoothHapClient.ACTION_HAP_CONNECTION_STATE_CHANGED:
+ if (state == BluetoothProfile.STATE_CONNECTED) {
+ updateHearingDeviceActiveTime(
+ device,
+ HEARING_DEVICE_ACTIVE_EVENT_REPORTED__DEVICE_TYPE__LE_AUDIO
+ );
+ }
+ break;
default:
Log.w(TAG, "Received unknown intent " + intent);
break;
@@ -389,37 +425,6 @@ public class MetricsLogger {
return true;
}
- /**
- * Log profile connection event by incrementing an internal counter for that profile. This log
- * persists over adapter enable/disable and only get cleared when metrics are dumped or when
- * Bluetooth process is killed.
- *
- * @param profileId Bluetooth profile that is connected at this event
- */
- public static void logProfileConnectionEvent(ProfileId profileId) {
- synchronized (sProfileConnectionCounts) {
- sProfileConnectionCounts.merge(profileId, 1, Integer::sum);
- }
- }
-
- /**
- * Dump collected metrics into proto using a builder. Clean up internal data after the dump.
- *
- * @param metricsBuilder proto builder for {@link BluetoothLog}
- */
- public static void dumpProto(BluetoothLog.Builder metricsBuilder) {
- synchronized (sProfileConnectionCounts) {
- sProfileConnectionCounts.forEach(
- (key, value) ->
- metricsBuilder.addProfileConnectionStats(
- ProfileConnectionStats.newBuilder()
- .setProfileId(key)
- .setNumTimesConnected(value)
- .build()));
- sProfileConnectionCounts.clear();
- }
- }
-
protected void scheduleDrains() {
Log.i(TAG, "setCounterMetricsAlarm()");
if (mAlarmManager == null) {
@@ -682,7 +687,8 @@ public class MetricsLogger {
int numOngoingScan,
boolean isScreenOn,
boolean isAppDead,
- int appImportance) {
+ int appImportance,
+ String attributionTag) {
BluetoothStatsLog.write(
BluetoothStatsLog.LE_APP_SCAN_STATE_CHANGED,
uids,
@@ -698,7 +704,8 @@ public class MetricsLogger {
numOngoingScan,
isScreenOn,
isAppDead,
- convertAppImportance(appImportance));
+ convertAppImportance(appImportance),
+ attributionTag);
}
/** Logs the radio scan stats with app attribution when the radio scan stopped. */
@@ -711,7 +718,8 @@ public class MetricsLogger {
long scanWindowMillis,
boolean isScreenOn,
long scanDurationMillis,
- int appImportance) {
+ int appImportance,
+ String attributionTag) {
BluetoothStatsLog.write(
BluetoothStatsLog.LE_RADIO_SCAN_STOPPED,
uids,
@@ -722,7 +730,8 @@ public class MetricsLogger {
scanWindowMillis,
isScreenOn,
scanDurationMillis,
- convertAppImportance(appImportance));
+ convertAppImportance(appImportance),
+ attributionTag);
}
/** Logs the advertise stats with app attribution when the advertise state changed. */
@@ -738,7 +747,8 @@ public class MetricsLogger {
boolean isExtendedAdv,
int instanceCount,
long advDurationMs,
- int appImportance) {
+ int appImportance,
+ String attributionTag) {
BluetoothStatsLog.write(
BluetoothStatsLog.LE_ADV_STATE_CHANGED,
uids,
@@ -752,7 +762,8 @@ public class MetricsLogger {
isExtendedAdv,
instanceCount,
advDurationMs,
- convertAppImportance(appImportance));
+ convertAppImportance(appImportance),
+ attributionTag);
}
protected String getAllowlistedDeviceNameHash(
@@ -945,4 +956,56 @@ public class MetricsLogger {
syncStatus,
getRemoteDeviceInfoProto(device, false));
}
+
+ void logHearingDeviceActiveEvent(BluetoothDevice device, int type, int timePeriod) {
+ BluetoothStatsLog.write(
+ BluetoothStatsLog.HEARING_DEVICE_ACTIVE_EVENT_REPORTED,
+ type,
+ timePeriod,
+ getRemoteDeviceInfoProto(device, true));
+ }
+
+ void updateHearingDeviceActiveTime(BluetoothDevice device, int deviceTypeProto) {
+ // Time comparison includes a +/- 1 hour tolerance to prevent data loss
+ updateLastActiveTime(
+ device,
+ deviceTypeProto,
+ HEARING_DEVICE_ACTIVE_EVENT_REPORTED__TIME_PERIOD__DAY,
+ "last_active_day",
+ (now, lastActive) -> now.isAfter(lastActive.plusDays(1).minusHours(1)));
+ updateLastActiveTime(
+ device,
+ deviceTypeProto,
+ HEARING_DEVICE_ACTIVE_EVENT_REPORTED__TIME_PERIOD__WEEK,
+ "last_active_week",
+ (now, lastActive) -> now.isAfter(lastActive.plusWeeks(1).minusHours(1)));
+ updateLastActiveTime(
+ device,
+ deviceTypeProto,
+ HEARING_DEVICE_ACTIVE_EVENT_REPORTED__TIME_PERIOD__MONTH,
+ "last_active_month",
+ (now, lastActive) -> now.isAfter(lastActive.plusMonths(1).minusHours(1)));
+ }
+
+ private void updateLastActiveTime(
+ BluetoothDevice device,
+ int deviceTypeProto,
+ int timePeriodProto,
+ String timePeriodSettingsKey,
+ BiPredicate<LocalDateTime, LocalDateTime> timeComparison) {
+ final ContentResolver contentResolver = mAdapterService.getContentResolver();
+ final String lastActive = Settings.Secure.getString(contentResolver, timePeriodSettingsKey);
+ final LocalDateTime now = LocalDateTime.now(ZoneId.systemDefault());
+ if (lastActive == null || timeComparison.test(now, LocalDateTime.parse(lastActive))) {
+ Settings.Secure.putString(contentResolver, timePeriodSettingsKey, now.toString());
+ logHearingDeviceActiveEvent(device, deviceTypeProto, timePeriodProto);
+ }
+ }
+
+ private boolean isMedicalDevice(BluetoothDevice device) {
+ final String deviceName = mAdapterService.getRemoteName(device);
+ final List<String> wordBreakdownList = getWordBreakdownList(deviceName);
+ boolean isMedicalDevice = !getMatchedStringForMedicalDevice(wordBreakdownList).isEmpty();
+ return isMedicalDevice;
+ }
}
diff --git a/android/app/src/com/android/bluetooth/btservice/ProfileService.java b/android/app/src/com/android/bluetooth/btservice/ProfileService.java
index 8a0fc82555..e8ea20de03 100644
--- a/android/app/src/com/android/bluetooth/btservice/ProfileService.java
+++ b/android/app/src/com/android/bluetooth/btservice/ProfileService.java
@@ -24,7 +24,6 @@ import android.content.pm.PackageManager;
import android.os.IBinder;
import android.util.Log;
-import com.android.bluetooth.BluetoothMetricsProto;
import com.android.bluetooth.Utils;
/** Base class for a background service that runs a Bluetooth profile */
@@ -147,17 +146,6 @@ public abstract class ProfileService extends ContextWrapper {
}
/**
- * Support dumping scan events from GattService
- *
- * @param builder metrics proto builder
- */
- // Suppressed since this is called from framework
- @SuppressLint("AndroidFrameworkRequiresPermission")
- public void dumpProto(BluetoothMetricsProto.BluetoothLog.Builder builder) {
- // Do nothing
- }
-
- /**
* Append an indented String for adding dumpsys support to subclasses.
*
* @param sb StringBuilder from the profile.
diff --git a/android/app/src/com/android/bluetooth/btservice/RemoteDevices.java b/android/app/src/com/android/bluetooth/btservice/RemoteDevices.java
index 89e80650b1..c49659863b 100644
--- a/android/app/src/com/android/bluetooth/btservice/RemoteDevices.java
+++ b/android/app/src/com/android/bluetooth/btservice/RemoteDevices.java
@@ -27,6 +27,7 @@ import static com.android.modules.utils.build.SdkLevel.isAtLeastV;
import static java.util.Objects.requireNonNullElseGet;
+import android.annotation.NonNull;
import android.annotation.RequiresPermission;
import android.annotation.SuppressLint;
import android.app.Activity;
@@ -43,8 +44,11 @@ import android.bluetooth.BluetoothProtoEnums;
import android.bluetooth.BluetoothSinkAudioPolicy;
import android.bluetooth.BluetoothUtils;
import android.bluetooth.IBluetoothConnectionCallback;
+import android.content.AttributionSource;
import android.content.Intent;
+import android.content.pm.Attribution;
import android.net.MacAddress;
+import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
@@ -64,9 +68,13 @@ import com.android.modules.utils.build.SdkLevel;
import java.nio.charset.StandardCharsets;
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.LinkedHashMap;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import java.util.function.Predicate;
@@ -329,6 +337,7 @@ public class RemoteDevices {
}
class DeviceProperties {
+ private static final int MAX_PACKAGE_NAMES = 4;
private String mName;
private byte[] mAddress;
private String mIdentityAddress;
@@ -354,6 +363,16 @@ public class RemoteDevices {
@VisibleForTesting boolean mHfpBatteryIndicator = false;
private BluetoothSinkAudioPolicy mAudioPolicy;
+ // LRU cache of package names associated to this device
+ private final Set<String> mPackages =
+ Collections.newSetFromMap(
+ new LinkedHashMap<String, Boolean>() {
+ // This is called on every add. Returning true removes the eldest entry.
+ protected boolean removeEldestEntry(Map.Entry<String, Boolean> eldest) {
+ return size() >= MAX_PACKAGE_NAMES;
+ }
+ });
+
DeviceProperties() {
mBondState = BluetoothDevice.BOND_NONE;
}
@@ -858,6 +877,22 @@ public class RemoteDevices {
return mModelName;
}
}
+
+ @NonNull
+ public String[] getPackages() {
+ synchronized (mObject) {
+ return mPackages.toArray(new String[0]);
+ }
+ }
+
+ public void addPackage(String packageName) {
+ synchronized (mObject) {
+ // Removing the package ensures that the LRU cache order is updated. Adding it back
+ // will make it the newest.
+ mPackages.remove(packageName);
+ mPackages.add(packageName);
+ }
+ }
}
private void sendUuidIntent(BluetoothDevice device, DeviceProperties prop, boolean success) {
@@ -910,15 +945,6 @@ public class RemoteDevices {
properties.setBondingInitiatedLocally(true);
}
- /**
- * Update battery level in device properties
- *
- * @param device The remote device to be updated
- * @param batteryLevel Battery level Indicator between 0-100, {@link
- * BluetoothDevice#BATTERY_LEVEL_UNKNOWN} is error
- * @param isBas true if the battery level is from the battery service
- */
- @VisibleForTesting
void updateBatteryLevel(BluetoothDevice device, int batteryLevel, boolean isBas) {
if (device == null || batteryLevel < 0 || batteryLevel > 100) {
warnLog(
@@ -952,12 +978,6 @@ public class RemoteDevices {
Log.d(TAG, "Updated device " + device + " battery level to " + newBatteryLevel + "%");
}
- /**
- * Reset battery level property to {@link BluetoothDevice#BATTERY_LEVEL_UNKNOWN} for a device
- *
- * @param device device whose battery level property needs to be reset
- */
- @VisibleForTesting
void resetBatteryLevel(BluetoothDevice device, boolean isBas) {
if (device == null) {
warnLog("Device is null");
@@ -1589,6 +1609,28 @@ public class RemoteDevices {
// Bond loss detected, add to the count.
mAdapterService.getDatabase().updateKeyMissingCount(bluetoothDevice, true);
+ // Some apps are not able to handle the key missing broadcast, so we need to remove
+ // the bond to prevent them from misbehaving.
+ // TODO (b/402854328): Remove when the misbehaving apps are updated
+ if (bondLossIopFixNeeded(bluetoothDevice)) {
+ DeviceProperties deviceProperties = getDeviceProperties(bluetoothDevice);
+ if (deviceProperties == null) {
+ return;
+ }
+ String[] packages = deviceProperties.getPackages();
+ if (packages.length == 0) {
+ return;
+ }
+
+ Log.w(
+ TAG,
+ "Removing "
+ + bluetoothDevice
+ + " on behalf of: "
+ + Arrays.toString(packages));
+ bluetoothDevice.removeBond();
+ }
+
if (Flags.keyMissingPublic()) {
mAdapterService.sendOrderedBroadcast(
intent,
@@ -2007,6 +2049,55 @@ public class RemoteDevices {
device, batteryChargeIndicatorToPercentage(batteryLevel), /* isBas= */ false);
}
+ private static final String[] BOND_LOSS_IOP_PACKAGES = {
+ "com.sjm.crmd.patientApp_Android", "com.abbott.crm.ngq.patient",
+ };
+
+ private static final Set<String> BOND_LOSS_IOP_DEVICE_NAMES = Set.of("CM", "DM");
+
+ // TODO (b/402854328): Remove when the misbehaving apps are updated
+ public boolean bondLossIopFixNeeded(BluetoothDevice device) {
+ DeviceProperties deviceProperties = getDeviceProperties(device);
+ if (deviceProperties == null) {
+ return false;
+ }
+
+ String deviceName = deviceProperties.getName();
+ if (deviceName == null) {
+ return false;
+ }
+
+ String[] packages = deviceProperties.getPackages();
+ if (packages.length == 0) {
+ return false;
+ }
+
+ if (!BOND_LOSS_IOP_DEVICE_NAMES.contains(deviceName)) {
+ return false;
+ }
+
+ for (String iopFixPackage : BOND_LOSS_IOP_PACKAGES) {
+ for (String packageName : packages) {
+ if (packageName.contains(iopFixPackage)
+ && !Utils.checkCallerTargetSdk(
+ mAdapterService, packageName, Build.VERSION_CODES.BAKLAVA)) {
+ Log.w(
+ TAG,
+ "bondLossIopFixNeeded(): "
+ + " IOP fix needed for "
+ + device
+ + " name: "
+ + deviceName
+ + " package: "
+ + packageName);
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
private static void errorLog(String msg) {
Log.e(TAG, msg);
}
diff --git a/android/app/src/com/android/bluetooth/btservice/SilenceDeviceManager.java b/android/app/src/com/android/bluetooth/btservice/SilenceDeviceManager.java
index b250e2ffe9..90d9a4bee6 100644
--- a/android/app/src/com/android/bluetooth/btservice/SilenceDeviceManager.java
+++ b/android/app/src/com/android/bluetooth/btservice/SilenceDeviceManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
@@ -31,7 +31,6 @@ import android.util.Log;
import com.android.bluetooth.Utils;
import com.android.bluetooth.a2dp.A2dpService;
import com.android.bluetooth.hfp.HeadsetService;
-import com.android.internal.annotations.VisibleForTesting;
import java.util.ArrayList;
import java.util.HashMap;
@@ -205,7 +204,6 @@ public class SilenceDeviceManager {
mSilenceDevices.clear();
}
- @VisibleForTesting
boolean setSilenceMode(BluetoothDevice device, boolean silence) {
Log.d(TAG, "setSilenceMode: " + device + ", " + silence);
mHandler.obtainMessage(
diff --git a/android/app/src/com/android/bluetooth/btservice/bluetoothKeystore/BluetoothKeystoreNativeInterface.java b/android/app/src/com/android/bluetooth/btservice/bluetoothKeystore/BluetoothKeystoreNativeInterface.java
index 073aa34302..09761f58d9 100644
--- a/android/app/src/com/android/bluetooth/btservice/bluetoothKeystore/BluetoothKeystoreNativeInterface.java
+++ b/android/app/src/com/android/bluetooth/btservice/bluetoothKeystore/BluetoothKeystoreNativeInterface.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/android/app/src/com/android/bluetooth/btservice/bluetoothKeystore/BluetoothKeystoreService.java b/android/app/src/com/android/bluetooth/btservice/bluetoothKeystore/BluetoothKeystoreService.java
index 020692ae6f..26922d0aff 100644
--- a/android/app/src/com/android/bluetooth/btservice/bluetoothKeystore/BluetoothKeystoreService.java
+++ b/android/app/src/com/android/bluetooth/btservice/bluetoothKeystore/BluetoothKeystoreService.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/android/app/src/com/android/bluetooth/btservice/storage/AudioPolicyEntity.java b/android/app/src/com/android/bluetooth/btservice/storage/AudioPolicyEntity.java
index 76ba89e0a4..2f70150270 100644
--- a/android/app/src/com/android/bluetooth/btservice/storage/AudioPolicyEntity.java
+++ b/android/app/src/com/android/bluetooth/btservice/storage/AudioPolicyEntity.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/src/com/android/bluetooth/btservice/storage/BluetoothDatabaseMigration.java b/android/app/src/com/android/bluetooth/btservice/storage/BluetoothDatabaseMigration.java
index c083c04e01..bcaad1ef16 100644
--- a/android/app/src/com/android/bluetooth/btservice/storage/BluetoothDatabaseMigration.java
+++ b/android/app/src/com/android/bluetooth/btservice/storage/BluetoothDatabaseMigration.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/src/com/android/bluetooth/btservice/storage/CustomizedMetadataEntity.java b/android/app/src/com/android/bluetooth/btservice/storage/CustomizedMetadataEntity.java
index 4b224c24d0..d7cb75cbbf 100644
--- a/android/app/src/com/android/bluetooth/btservice/storage/CustomizedMetadataEntity.java
+++ b/android/app/src/com/android/bluetooth/btservice/storage/CustomizedMetadataEntity.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/android/app/src/com/android/bluetooth/btservice/storage/DatabaseManager.java b/android/app/src/com/android/bluetooth/btservice/storage/DatabaseManager.java
index ca0d8ac3eb..b5724c4fa4 100644
--- a/android/app/src/com/android/bluetooth/btservice/storage/DatabaseManager.java
+++ b/android/app/src/com/android/bluetooth/btservice/storage/DatabaseManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/android/app/src/com/android/bluetooth/btservice/storage/Metadata.java b/android/app/src/com/android/bluetooth/btservice/storage/Metadata.java
index 28b286280f..d60ccadc21 100644
--- a/android/app/src/com/android/bluetooth/btservice/storage/Metadata.java
+++ b/android/app/src/com/android/bluetooth/btservice/storage/Metadata.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/android/app/src/com/android/bluetooth/btservice/storage/MetadataDao.java b/android/app/src/com/android/bluetooth/btservice/storage/MetadataDao.java
index 7db45bf9e3..be485b5c1e 100644
--- a/android/app/src/com/android/bluetooth/btservice/storage/MetadataDao.java
+++ b/android/app/src/com/android/bluetooth/btservice/storage/MetadataDao.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/android/app/src/com/android/bluetooth/btservice/storage/MetadataDatabase.java b/android/app/src/com/android/bluetooth/btservice/storage/MetadataDatabase.java
index 00c52734a8..d535ab5ff8 100644
--- a/android/app/src/com/android/bluetooth/btservice/storage/MetadataDatabase.java
+++ b/android/app/src/com/android/bluetooth/btservice/storage/MetadataDatabase.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/android/app/src/com/android/bluetooth/btservice/storage/ProfilePrioritiesEntity.java b/android/app/src/com/android/bluetooth/btservice/storage/ProfilePrioritiesEntity.java
index 5fb23b9267..758a17e1c2 100644
--- a/android/app/src/com/android/bluetooth/btservice/storage/ProfilePrioritiesEntity.java
+++ b/android/app/src/com/android/bluetooth/btservice/storage/ProfilePrioritiesEntity.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/android/app/src/com/android/bluetooth/content_profiles/ContentProfileErrorReportUtils.java b/android/app/src/com/android/bluetooth/content_profiles/ContentProfileErrorReportUtils.java
index 72be2ec6b3..0b6d2179d6 100644
--- a/android/app/src/com/android/bluetooth/content_profiles/ContentProfileErrorReportUtils.java
+++ b/android/app/src/com/android/bluetooth/content_profiles/ContentProfileErrorReportUtils.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 The Android Open Source Project
+ * Copyright (C) 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.
diff --git a/android/app/src/com/android/bluetooth/csip/CsipSetCoordinatorService.java b/android/app/src/com/android/bluetooth/csip/CsipSetCoordinatorService.java
index 2b49f467a8..7a6597f5b0 100644
--- a/android/app/src/com/android/bluetooth/csip/CsipSetCoordinatorService.java
+++ b/android/app/src/com/android/bluetooth/csip/CsipSetCoordinatorService.java
@@ -17,7 +17,6 @@
package com.android.bluetooth.csip;
-import static android.Manifest.permission.BLUETOOTH_CONNECT;
import static android.Manifest.permission.BLUETOOTH_PRIVILEGED;
import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_ALLOWED;
import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
@@ -31,7 +30,6 @@ import static java.util.Objects.requireNonNullElseGet;
import android.annotation.CallbackExecutor;
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.annotation.RequiresPermission;
import android.bluetooth.BluetoothCsipSetCoordinator;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
@@ -40,7 +38,6 @@ import android.bluetooth.BluetoothUuid;
import android.bluetooth.IBluetoothCsipSetCoordinator;
import android.bluetooth.IBluetoothCsipSetCoordinatorCallback;
import android.bluetooth.IBluetoothCsipSetCoordinatorLockCallback;
-import android.content.AttributionSource;
import android.content.Intent;
import android.os.Handler;
import android.os.HandlerThread;
@@ -152,7 +149,7 @@ public class CsipSetCoordinatorService extends ProfileService {
@Override
protected IProfileServiceBinder initBinder() {
- return new BluetoothCsisBinder(this);
+ return new CsipSetCoordinatorServiceBinder(this);
}
@Override
@@ -991,171 +988,6 @@ public class CsipSetCoordinatorService extends ProfileService {
BluetoothProfile.CSIP_SET_COORDINATOR, device, fromState, toState);
}
- /** Binder object: must be a static class or memory leak may occur */
- @VisibleForTesting
- static class BluetoothCsisBinder extends IBluetoothCsipSetCoordinator.Stub
- implements IProfileServiceBinder {
- private CsipSetCoordinatorService mService;
-
- BluetoothCsisBinder(CsipSetCoordinatorService svc) {
- mService = svc;
- }
-
- @Override
- public void cleanup() {
- mService = null;
- }
-
- @RequiresPermission(allOf = {BLUETOOTH_CONNECT, BLUETOOTH_PRIVILEGED})
- private CsipSetCoordinatorService getService(AttributionSource source) {
- // Cache mService because it can change while getService is called
- CsipSetCoordinatorService service = mService;
-
- if (Utils.isInstrumentationTestMode()) {
- return service;
- }
-
- if (!Utils.checkServiceAvailable(service, TAG)
- || !Utils.checkCallerIsSystemOrActiveOrManagedUser(service, TAG)
- || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
- return null;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- return service;
- }
-
- @Override
- public List<BluetoothDevice> getConnectedDevices(AttributionSource source) {
- requireNonNull(source);
-
- CsipSetCoordinatorService service = getService(source);
- if (service == null) {
- return Collections.emptyList();
- }
-
- return service.getConnectedDevices();
- }
-
- @Override
- public List<BluetoothDevice> getDevicesMatchingConnectionStates(
- int[] states, AttributionSource source) {
- requireNonNull(source);
-
- CsipSetCoordinatorService service = getService(source);
- if (service == null) {
- return Collections.emptyList();
- }
-
- return service.getDevicesMatchingConnectionStates(states);
- }
-
- @Override
- public int getConnectionState(BluetoothDevice device, AttributionSource source) {
- requireNonNull(device);
- requireNonNull(source);
-
- CsipSetCoordinatorService service = getService(source);
- if (service == null) {
- return STATE_DISCONNECTED;
- }
-
- return service.getConnectionState(device);
- }
-
- @Override
- public boolean setConnectionPolicy(
- BluetoothDevice device, int connectionPolicy, AttributionSource source) {
- requireNonNull(device);
- requireNonNull(source);
-
- CsipSetCoordinatorService service = getService(source);
- if (service == null) {
- return false;
- }
-
- return service.setConnectionPolicy(device, connectionPolicy);
- }
-
- @Override
- public int getConnectionPolicy(BluetoothDevice device, AttributionSource source) {
- requireNonNull(device);
- requireNonNull(source);
-
- CsipSetCoordinatorService service = getService(source);
- if (service == null) {
- return CONNECTION_POLICY_UNKNOWN;
- }
-
- return service.getConnectionPolicy(device);
- }
-
- @Override
- public ParcelUuid lockGroup(
- int groupId,
- @NonNull IBluetoothCsipSetCoordinatorLockCallback callback,
- AttributionSource source) {
- requireNonNull(callback);
- requireNonNull(source);
-
- CsipSetCoordinatorService service = getService(source);
- if (service == null) {
- return null;
- }
-
- UUID lockUuid = service.lockGroup(groupId, callback);
- return lockUuid == null ? null : new ParcelUuid(lockUuid);
- }
-
- @Override
- public void unlockGroup(@NonNull ParcelUuid lockUuid, AttributionSource source) {
- requireNonNull(lockUuid);
- requireNonNull(source);
-
- CsipSetCoordinatorService service = getService(source);
- if (service == null) {
- return;
- }
-
- service.unlockGroup(lockUuid.getUuid());
- }
-
- @Override
- public List<Integer> getAllGroupIds(ParcelUuid uuid, AttributionSource source) {
- requireNonNull(uuid);
- requireNonNull(source);
-
- CsipSetCoordinatorService service = getService(source);
- if (service == null) {
- return Collections.emptyList();
- }
-
- return service.getAllGroupIds(uuid);
- }
-
- @Override
- public Map<Integer, ParcelUuid> getGroupUuidMapByDevice(
- BluetoothDevice device, AttributionSource source) {
- CsipSetCoordinatorService service = getService(source);
- if (service == null) {
- return null;
- }
-
- return service.getGroupUuidMapByDevice(device);
- }
-
- @Override
- public int getDesiredGroupSize(int groupId, AttributionSource source) {
- CsipSetCoordinatorService service = getService(source);
- if (service == null) {
- return IBluetoothCsipSetCoordinator.CSIS_GROUP_SIZE_UNKNOWN;
- }
-
- return service.getDesiredGroupSize(groupId);
- }
- }
-
@Override
public void dump(StringBuilder sb) {
super.dump(sb);
diff --git a/android/app/src/com/android/bluetooth/csip/CsipSetCoordinatorServiceBinder.java b/android/app/src/com/android/bluetooth/csip/CsipSetCoordinatorServiceBinder.java
new file mode 100644
index 0000000000..5b08c1983b
--- /dev/null
+++ b/android/app/src/com/android/bluetooth/csip/CsipSetCoordinatorServiceBinder.java
@@ -0,0 +1,194 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.bluetooth.csip;
+
+import static android.Manifest.permission.BLUETOOTH_CONNECT;
+import static android.Manifest.permission.BLUETOOTH_PRIVILEGED;
+import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_UNKNOWN;
+import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTED;
+
+import static java.util.Objects.requireNonNull;
+
+import android.annotation.NonNull;
+import android.annotation.RequiresPermission;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.IBluetoothCsipSetCoordinator;
+import android.bluetooth.IBluetoothCsipSetCoordinatorLockCallback;
+import android.content.AttributionSource;
+import android.os.ParcelUuid;
+
+import com.android.bluetooth.Utils;
+import com.android.bluetooth.btservice.ProfileService.IProfileServiceBinder;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+class CsipSetCoordinatorServiceBinder extends IBluetoothCsipSetCoordinator.Stub
+ implements IProfileServiceBinder {
+ private static final String TAG = CsipSetCoordinatorServiceBinder.class.getSimpleName();
+
+ private CsipSetCoordinatorService mService;
+
+ CsipSetCoordinatorServiceBinder(CsipSetCoordinatorService svc) {
+ mService = svc;
+ }
+
+ @Override
+ public void cleanup() {
+ mService = null;
+ }
+
+ @RequiresPermission(allOf = {BLUETOOTH_CONNECT, BLUETOOTH_PRIVILEGED})
+ private CsipSetCoordinatorService getService(AttributionSource source) {
+ CsipSetCoordinatorService service = mService;
+
+ if (Utils.isInstrumentationTestMode()) {
+ return service;
+ }
+
+ if (!Utils.checkServiceAvailable(service, TAG)
+ || !Utils.checkCallerIsSystemOrActiveOrManagedUser(service, TAG)
+ || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
+ return null;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service;
+ }
+
+ @Override
+ public List<BluetoothDevice> getConnectedDevices(AttributionSource source) {
+ requireNonNull(source);
+
+ CsipSetCoordinatorService service = getService(source);
+ if (service == null) {
+ return Collections.emptyList();
+ }
+ return service.getConnectedDevices();
+ }
+
+ @Override
+ public List<BluetoothDevice> getDevicesMatchingConnectionStates(
+ int[] states, AttributionSource source) {
+ requireNonNull(source);
+
+ CsipSetCoordinatorService service = getService(source);
+ if (service == null) {
+ return Collections.emptyList();
+ }
+ return service.getDevicesMatchingConnectionStates(states);
+ }
+
+ @Override
+ public int getConnectionState(BluetoothDevice device, AttributionSource source) {
+ requireNonNull(device);
+ requireNonNull(source);
+
+ CsipSetCoordinatorService service = getService(source);
+ if (service == null) {
+ return STATE_DISCONNECTED;
+ }
+ return service.getConnectionState(device);
+ }
+
+ @Override
+ public boolean setConnectionPolicy(
+ BluetoothDevice device, int connectionPolicy, AttributionSource source) {
+ requireNonNull(device);
+ requireNonNull(source);
+
+ CsipSetCoordinatorService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+ return service.setConnectionPolicy(device, connectionPolicy);
+ }
+
+ @Override
+ public int getConnectionPolicy(BluetoothDevice device, AttributionSource source) {
+ requireNonNull(device);
+ requireNonNull(source);
+
+ CsipSetCoordinatorService service = getService(source);
+ if (service == null) {
+ return CONNECTION_POLICY_UNKNOWN;
+ }
+ return service.getConnectionPolicy(device);
+ }
+
+ @Override
+ public ParcelUuid lockGroup(
+ int groupId,
+ @NonNull IBluetoothCsipSetCoordinatorLockCallback callback,
+ AttributionSource source) {
+ requireNonNull(callback);
+ requireNonNull(source);
+
+ CsipSetCoordinatorService service = getService(source);
+ if (service == null) {
+ return null;
+ }
+
+ UUID lockUuid = service.lockGroup(groupId, callback);
+ return lockUuid == null ? null : new ParcelUuid(lockUuid);
+ }
+
+ @Override
+ public void unlockGroup(@NonNull ParcelUuid lockUuid, AttributionSource source) {
+ requireNonNull(lockUuid);
+ requireNonNull(source);
+
+ CsipSetCoordinatorService service = getService(source);
+ if (service == null) {
+ return;
+ }
+ service.unlockGroup(lockUuid.getUuid());
+ }
+
+ @Override
+ public List<Integer> getAllGroupIds(ParcelUuid uuid, AttributionSource source) {
+ requireNonNull(uuid);
+ requireNonNull(source);
+
+ CsipSetCoordinatorService service = getService(source);
+ if (service == null) {
+ return Collections.emptyList();
+ }
+ return service.getAllGroupIds(uuid);
+ }
+
+ @Override
+ public Map<Integer, ParcelUuid> getGroupUuidMapByDevice(
+ BluetoothDevice device, AttributionSource source) {
+ CsipSetCoordinatorService service = getService(source);
+ if (service == null) {
+ return null;
+ }
+ return service.getGroupUuidMapByDevice(device);
+ }
+
+ @Override
+ public int getDesiredGroupSize(int groupId, AttributionSource source) {
+ CsipSetCoordinatorService service = getService(source);
+ if (service == null) {
+ return IBluetoothCsipSetCoordinator.CSIS_GROUP_SIZE_UNKNOWN;
+ }
+ return service.getDesiredGroupSize(groupId);
+ }
+}
diff --git a/android/app/src/com/android/bluetooth/gatt/AdvertiseBinder.kt b/android/app/src/com/android/bluetooth/gatt/AdvertiseBinder.kt
index 02f4f9ff98..9d08625db7 100644
--- a/android/app/src/com/android/bluetooth/gatt/AdvertiseBinder.kt
+++ b/android/app/src/com/android/bluetooth/gatt/AdvertiseBinder.kt
@@ -1,5 +1,5 @@
/*
- * Copyright 2025 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/android/app/src/com/android/bluetooth/gatt/AppAdvertiseStats.java b/android/app/src/com/android/bluetooth/gatt/AppAdvertiseStats.java
index b9ebfad69f..44154b31bd 100644
--- a/android/app/src/com/android/bluetooth/gatt/AppAdvertiseStats.java
+++ b/android/app/src/com/android/bluetooth/gatt/AppAdvertiseStats.java
@@ -35,7 +35,6 @@ import androidx.annotation.VisibleForTesting;
import com.android.bluetooth.BluetoothStatsLog;
import com.android.bluetooth.btservice.MetricsLogger;
-import com.android.bluetooth.flags.Flags;
import java.time.Duration;
import java.time.Instant;
@@ -219,14 +218,13 @@ class AppAdvertiseStats {
}
void recordAdvertiseErrorCount(int status) {
- if (Flags.bleScanAdvMetricsRedesign()) {
- BluetoothStatsLog.write(
- BluetoothStatsLog.LE_ADV_ERROR_REPORTED,
- new int[] {mAppUid},
- new String[] {mAppName},
- BluetoothStatsLog.LE_ADV_ERROR_REPORTED__LE_ADV_OP_CODE__ERROR_CODE_ON_START,
- convertStatusCode(status));
- }
+ BluetoothStatsLog.write(
+ BluetoothStatsLog.LE_ADV_ERROR_REPORTED,
+ new int[] {mAppUid},
+ new String[] {mAppName},
+ BluetoothStatsLog.LE_ADV_ERROR_REPORTED__LE_ADV_OP_CODE__ERROR_CODE_ON_START,
+ convertStatusCode(status),
+ getAttributionTag());
MetricsLogger.getInstance().cacheCount(BluetoothProtoEnums.LE_ADV_ERROR_ON_START_COUNT, 1);
}
@@ -355,6 +353,10 @@ class AppAdvertiseStats {
mAppImportance = importance;
}
+ private String getAttributionTag() {
+ return mAttributionTag != null ? mAttributionTag : "";
+ }
+
private static void recordAdvertiseDurationCount(
Duration duration, boolean isConnectable, boolean inPeriodic) {
if (duration.compareTo(Duration.ofMinutes(1)) < 0) {
@@ -416,22 +418,21 @@ class AppAdvertiseStats {
}
private void recordAdvertiseEnableCount(boolean enable, int instanceCount, long durationMs) {
- if (Flags.bleScanAdvMetricsRedesign()) {
- MetricsLogger.getInstance()
- .logAdvStateChanged(
- new int[] {mAppUid},
- new String[] {mAppName},
- enable /* enabled */,
- convertAdvInterval(mInterval),
- convertTxPowerLevel(mTxPowerLevel),
- mConnectable,
- mPeriodicAdvertisingEnabled,
- mScanResponseData != null && mScannable /* hasScanResponse */,
- !mLegacy /* isExtendedAdv */,
- instanceCount,
- durationMs,
- mAppImportance);
- }
+ MetricsLogger.getInstance()
+ .logAdvStateChanged(
+ new int[] {mAppUid},
+ new String[] {mAppName},
+ enable /* enabled */,
+ convertAdvInterval(mInterval),
+ convertTxPowerLevel(mTxPowerLevel),
+ mConnectable,
+ mPeriodicAdvertisingEnabled,
+ mScanResponseData != null && mScannable /* hasScanResponse */,
+ !mLegacy /* isExtendedAdv */,
+ instanceCount,
+ durationMs,
+ mAppImportance,
+ getAttributionTag());
if (enable) {
MetricsLogger.getInstance().cacheCount(BluetoothProtoEnums.LE_ADV_COUNT_ENABLE, 1);
if (mConnectable) {
diff --git a/android/app/src/com/android/bluetooth/gatt/DistanceMeasurementBinder.kt b/android/app/src/com/android/bluetooth/gatt/DistanceMeasurementBinder.kt
index a63b757904..4d0835c175 100644
--- a/android/app/src/com/android/bluetooth/gatt/DistanceMeasurementBinder.kt
+++ b/android/app/src/com/android/bluetooth/gatt/DistanceMeasurementBinder.kt
@@ -1,5 +1,5 @@
/*
- * Copyright 2025 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package com.android.bluetooth.gatt
import android.Manifest
diff --git a/android/app/src/com/android/bluetooth/gatt/DistanceMeasurementManager.java b/android/app/src/com/android/bluetooth/gatt/DistanceMeasurementManager.java
index 5494b442a6..186865c23a 100644
--- a/android/app/src/com/android/bluetooth/gatt/DistanceMeasurementManager.java
+++ b/android/app/src/com/android/bluetooth/gatt/DistanceMeasurementManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/src/com/android/bluetooth/gatt/DistanceMeasurementNativeInterface.java b/android/app/src/com/android/bluetooth/gatt/DistanceMeasurementNativeInterface.java
index f5118d01d7..8cc365c291 100644
--- a/android/app/src/com/android/bluetooth/gatt/DistanceMeasurementNativeInterface.java
+++ b/android/app/src/com/android/bluetooth/gatt/DistanceMeasurementNativeInterface.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 The Android Open Source Project
+ * Copyright (C) 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.
diff --git a/android/app/src/com/android/bluetooth/gatt/DistanceMeasurementTracker.java b/android/app/src/com/android/bluetooth/gatt/DistanceMeasurementTracker.java
index 0885d393fe..dee39179af 100644
--- a/android/app/src/com/android/bluetooth/gatt/DistanceMeasurementTracker.java
+++ b/android/app/src/com/android/bluetooth/gatt/DistanceMeasurementTracker.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/src/com/android/bluetooth/gatt/GattNativeInterface.java b/android/app/src/com/android/bluetooth/gatt/GattNativeInterface.java
index 5a19a96186..37699ff2e1 100644
--- a/android/app/src/com/android/bluetooth/gatt/GattNativeInterface.java
+++ b/android/app/src/com/android/bluetooth/gatt/GattNativeInterface.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/src/com/android/bluetooth/gatt/GattObjectsFactory.java b/android/app/src/com/android/bluetooth/gatt/GattObjectsFactory.java
index 0279b2b199..28ecaa7b4f 100644
--- a/android/app/src/com/android/bluetooth/gatt/GattObjectsFactory.java
+++ b/android/app/src/com/android/bluetooth/gatt/GattObjectsFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/src/com/android/bluetooth/gatt/GattService.java b/android/app/src/com/android/bluetooth/gatt/GattService.java
index 65e0497420..6e5faefa9f 100644
--- a/android/app/src/com/android/bluetooth/gatt/GattService.java
+++ b/android/app/src/com/android/bluetooth/gatt/GattService.java
@@ -24,8 +24,8 @@ import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTED;
import static android.bluetooth.BluetoothUtils.toAnonymizedAddress;
import static com.android.bluetooth.Utils.callbackToApp;
-import static com.android.bluetooth.Utils.callerIsSystemOrActiveOrManagedUser;
import static com.android.bluetooth.Utils.checkCallerTargetSdk;
+import static com.android.bluetooth.Utils.checkConnectPermissionForDataDelivery;
import static com.android.bluetooth.util.AttributionSourceUtil.getLastAttributionTag;
import static java.util.Objects.requireNonNull;
@@ -43,7 +43,6 @@ import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothProtoEnums;
import android.bluetooth.BluetoothStatusCodes;
-import android.bluetooth.IBluetoothGatt;
import android.bluetooth.IBluetoothGattCallback;
import android.bluetooth.IBluetoothGattServerCallback;
import android.companion.CompanionDeviceManager;
@@ -61,7 +60,6 @@ import android.provider.Settings;
import android.sysprop.BluetoothProperties;
import android.util.Log;
-import com.android.bluetooth.BluetoothMetricsProto;
import com.android.bluetooth.BluetoothStatsLog;
import com.android.bluetooth.R;
import com.android.bluetooth.Utils;
@@ -213,7 +211,7 @@ public class GattService extends ProfileService {
@Override
protected IProfileServiceBinder initBinder() {
- return new BluetoothGattBinder(this);
+ return new GattServiceBinder(this);
}
@Override
@@ -264,6 +262,10 @@ public class GattService extends ProfileService {
return mScanController;
}
+ CompanionDeviceManager getCompanionDeviceManager() {
+ return mCompanionDeviceManager;
+ }
+
@Override
protected void setTestModeEnabled(boolean enableTestMode) {
if (mScanController != null) {
@@ -331,479 +333,6 @@ public class GattService extends ProfileService {
}
}
- /** Handlers for incoming service calls */
- @VisibleForTesting
- static class BluetoothGattBinder extends IBluetoothGatt.Stub implements IProfileServiceBinder {
- private GattService mService;
-
- BluetoothGattBinder(GattService svc) {
- mService = svc;
- }
-
- @Override
- public void cleanup() {
- mService = null;
- }
-
- private GattService getService() {
- // Cache mService because it can change while getService is called
- GattService service = mService;
-
- if (service == null || !service.isAvailable()) {
- Log.e(TAG, "getService() - Service requested, but not available!");
- return null;
- }
-
- return service;
- }
-
- @Override
- public List<BluetoothDevice> getDevicesMatchingConnectionStates(
- int[] states, AttributionSource source) {
- GattService service = getService();
- if (service == null) {
- return Collections.emptyList();
- }
- return service.getDevicesMatchingConnectionStates(states, source);
- }
-
- @Override
- public void registerClient(
- ParcelUuid uuid,
- IBluetoothGattCallback callback,
- boolean eattSupport,
- AttributionSource source) {
- GattService service = getService();
- if (service == null) {
- return;
- }
- service.registerClient(uuid.getUuid(), callback, eattSupport, source);
- }
-
- @Override
- public void unregisterClient(int clientIf, AttributionSource source) {
- GattService service = getService();
- if (service == null) {
- return;
- }
- service.unregisterClient(
- clientIf, source, ContextMap.RemoveReason.REASON_UNREGISTER_CLIENT);
- }
-
- @Override
- public void clientConnect(
- int clientIf,
- String address,
- int addressType,
- boolean isDirect,
- int transport,
- boolean opportunistic,
- int phy,
- AttributionSource source) {
- GattService service = getService();
- if (service == null) {
- return;
- }
- service.clientConnect(
- clientIf,
- address,
- addressType,
- isDirect,
- transport,
- opportunistic,
- phy,
- source);
- }
-
- @Override
- public void clientDisconnect(int clientIf, String address, AttributionSource source) {
- GattService service = getService();
- if (service == null) {
- return;
- }
- service.clientDisconnect(clientIf, address, source);
- }
-
- @Override
- public void clientSetPreferredPhy(
- int clientIf,
- String address,
- int txPhy,
- int rxPhy,
- int phyOptions,
- AttributionSource source) {
- GattService service = getService();
- if (service == null) {
- return;
- }
- service.clientSetPreferredPhy(clientIf, address, txPhy, rxPhy, phyOptions, source);
- }
-
- @Override
- public void clientReadPhy(int clientIf, String address, AttributionSource source) {
- GattService service = getService();
- if (service == null) {
- return;
- }
- service.clientReadPhy(clientIf, address, source);
- }
-
- @Override
- public void refreshDevice(int clientIf, String address, AttributionSource source) {
- GattService service = getService();
- if (service == null) {
- return;
- }
- service.refreshDevice(clientIf, address, source);
- }
-
- @Override
- public void discoverServices(int clientIf, String address, AttributionSource source) {
- GattService service = getService();
- if (service == null) {
- return;
- }
- service.discoverServices(clientIf, address, source);
- }
-
- @Override
- public void discoverServiceByUuid(
- int clientIf, String address, ParcelUuid uuid, AttributionSource source) {
- GattService service = getService();
- if (service == null) {
- return;
- }
- service.discoverServiceByUuid(clientIf, address, uuid.getUuid(), source);
- }
-
- @Override
- public void readCharacteristic(
- int clientIf, String address, int handle, int authReq, AttributionSource source) {
- GattService service = getService();
- if (service == null) {
- return;
- }
- service.readCharacteristic(clientIf, address, handle, authReq, source);
- }
-
- @Override
- public void readUsingCharacteristicUuid(
- int clientIf,
- String address,
- ParcelUuid uuid,
- int startHandle,
- int endHandle,
- int authReq,
- AttributionSource source) {
- GattService service = getService();
- if (service == null) {
- return;
- }
- service.readUsingCharacteristicUuid(
- clientIf, address, uuid.getUuid(), startHandle, endHandle, authReq, source);
- }
-
- @Override
- public int writeCharacteristic(
- int clientIf,
- String address,
- int handle,
- int writeType,
- int authReq,
- byte[] value,
- AttributionSource source) {
- GattService service = getService();
- if (service == null) {
- return BluetoothStatusCodes.ERROR_PROFILE_SERVICE_NOT_BOUND;
- }
- return service.writeCharacteristic(
- clientIf, address, handle, writeType, authReq, value, source);
- }
-
- @Override
- public void readDescriptor(
- int clientIf, String address, int handle, int authReq, AttributionSource source) {
- GattService service = getService();
- if (service == null) {
- return;
- }
- service.readDescriptor(clientIf, address, handle, authReq, source);
- }
-
- @Override
- public int writeDescriptor(
- int clientIf,
- String address,
- int handle,
- int authReq,
- byte[] value,
- AttributionSource source) {
- GattService service = getService();
- if (service == null) {
- return BluetoothStatusCodes.ERROR_PROFILE_SERVICE_NOT_BOUND;
- }
- return service.writeDescriptor(clientIf, address, handle, authReq, value, source);
- }
-
- @Override
- public void beginReliableWrite(int clientIf, String address, AttributionSource source) {
- GattService service = getService();
- if (service == null) {
- return;
- }
- service.beginReliableWrite(clientIf, address, source);
- }
-
- @Override
- public void endReliableWrite(
- int clientIf, String address, boolean execute, AttributionSource source) {
- GattService service = getService();
- if (service == null) {
- return;
- }
- service.endReliableWrite(clientIf, address, execute, source);
- }
-
- @Override
- public void registerForNotification(
- int clientIf,
- String address,
- int handle,
- boolean enable,
- AttributionSource source) {
- GattService service = getService();
- if (service == null) {
- return;
- }
- service.registerForNotification(clientIf, address, handle, enable, source);
- }
-
- @Override
- public void readRemoteRssi(int clientIf, String address, AttributionSource source) {
- GattService service = getService();
- if (service == null) {
- return;
- }
- service.readRemoteRssi(clientIf, address, source);
- }
-
- @Override
- public void configureMTU(int clientIf, String address, int mtu, AttributionSource source) {
- GattService service = getService();
- if (service == null) {
- return;
- }
- service.configureMTU(clientIf, address, mtu, source);
- }
-
- @Override
- public void connectionParameterUpdate(
- int clientIf, String address, int connectionPriority, AttributionSource source) {
- GattService service = getService();
- if (service == null) {
- return;
- }
- service.connectionParameterUpdate(clientIf, address, connectionPriority, source);
- }
-
- @Override
- public void leConnectionUpdate(
- int clientIf,
- String address,
- int minConnectionInterval,
- int maxConnectionInterval,
- int peripheralLatency,
- int supervisionTimeout,
- int minConnectionEventLen,
- int maxConnectionEventLen,
- AttributionSource source) {
- GattService service = getService();
- if (service == null) {
- return;
- }
- service.leConnectionUpdate(
- clientIf,
- address,
- minConnectionInterval,
- maxConnectionInterval,
- peripheralLatency,
- supervisionTimeout,
- minConnectionEventLen,
- maxConnectionEventLen,
- source);
- }
-
- @Override
- public int subrateModeRequest(
- int clientIf, BluetoothDevice device, int subrateMode, AttributionSource source) {
- GattService service = getService();
- if (service == null) {
- return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED;
- }
- if (!callerIsSystemOrActiveOrManagedUser(service, TAG, "subrateModeRequest")) {
- return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ALLOWED;
- }
-
- if (!Utils.checkConnectPermissionForDataDelivery(
- service, source, "GattService subrateModeRequest")) {
- return BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION;
- }
-
- Utils.enforceCdmAssociationIfNotBluetoothPrivileged(
- service, service.mCompanionDeviceManager, source, device);
-
- if (subrateMode < BluetoothGatt.SUBRATE_REQUEST_MODE_BALANCED
- || subrateMode > BluetoothGatt.SUBRATE_REQUEST_MODE_LOW_POWER) {
- throw new IllegalArgumentException("Subrate Mode not within valid range");
- }
-
- requireNonNull(device);
- String address = device.getAddress();
- if (!BluetoothAdapter.checkBluetoothAddress(address)) {
- throw new IllegalArgumentException("Invalid device address: " + address);
- }
-
- return service.subrateModeRequest(clientIf, device, subrateMode);
- }
-
- @Override
- public void registerServer(
- ParcelUuid uuid,
- IBluetoothGattServerCallback callback,
- boolean eattSupport,
- AttributionSource source) {
- GattService service = getService();
- if (service == null) {
- return;
- }
- service.registerServer(uuid.getUuid(), callback, eattSupport, source);
- }
-
- @Override
- public void unregisterServer(int serverIf, AttributionSource source) {
- GattService service = getService();
- if (service == null) {
- return;
- }
- service.unregisterServer(serverIf, source);
- }
-
- @Override
- public void serverConnect(
- int serverIf,
- String address,
- int addressType,
- boolean isDirect,
- int transport,
- AttributionSource source) {
- GattService service = getService();
- if (service == null) {
- return;
- }
- service.serverConnect(serverIf, address, addressType, isDirect, transport, source);
- }
-
- @Override
- public void serverDisconnect(int serverIf, String address, AttributionSource source) {
- GattService service = getService();
- if (service == null) {
- return;
- }
- service.serverDisconnect(serverIf, address, source);
- }
-
- @Override
- public void serverSetPreferredPhy(
- int serverIf,
- String address,
- int txPhy,
- int rxPhy,
- int phyOptions,
- AttributionSource source) {
- GattService service = getService();
- if (service == null) {
- return;
- }
- service.serverSetPreferredPhy(serverIf, address, txPhy, rxPhy, phyOptions, source);
- }
-
- @Override
- public void serverReadPhy(int clientIf, String address, AttributionSource source) {
- GattService service = getService();
- if (service == null) {
- return;
- }
- service.serverReadPhy(clientIf, address, source);
- }
-
- @Override
- public void addService(int serverIf, BluetoothGattService svc, AttributionSource source) {
- GattService service = getService();
- if (service == null) {
- return;
- }
- service.addService(serverIf, svc, source);
- }
-
- @Override
- public void removeService(int serverIf, int handle, AttributionSource source) {
- GattService service = getService();
- if (service == null) {
- return;
- }
- service.removeService(serverIf, handle, source);
- }
-
- @Override
- public void clearServices(int serverIf, AttributionSource source) {
- GattService service = getService();
- if (service == null) {
- return;
- }
- service.clearServices(serverIf, source);
- }
-
- @Override
- public void sendResponse(
- int serverIf,
- String address,
- int requestId,
- int status,
- int offset,
- byte[] value,
- AttributionSource source) {
- GattService service = getService();
- if (service == null) {
- return;
- }
- service.sendResponse(serverIf, address, requestId, status, offset, value, source);
- }
-
- @Override
- public int sendNotification(
- int serverIf,
- String address,
- int handle,
- boolean confirm,
- byte[] value,
- AttributionSource source) {
- GattService service = getService();
- if (service == null) {
- return BluetoothStatusCodes.ERROR_PROFILE_SERVICE_NOT_BOUND;
- }
- return service.sendNotification(serverIf, address, handle, confirm, value, source);
- }
-
- @Override
- public void disconnectAll(AttributionSource source) {
- GattService service = getService();
- if (service == null) {
- return;
- }
- service.disconnectAll(source);
- }
- }
-
/**************************************************************************
* Callback functions - CLIENT
*************************************************************************/
@@ -1427,8 +956,8 @@ public class GattService extends ProfileService {
@RequiresPermission(BLUETOOTH_CONNECT)
List<BluetoothDevice> getDevicesMatchingConnectionStates(
int[] states, AttributionSource source) {
- if (!Utils.checkConnectPermissionForDataDelivery(
- this, source, "GattService getDevicesMatchingConnectionStates")) {
+ if (!checkConnectPermissionForDataDelivery(
+ this, source, TAG, "getDevicesMatchingConnectionStates")) {
return Collections.emptyList();
}
@@ -1493,8 +1022,7 @@ public class GattService extends ProfileService {
IBluetoothGattCallback callback,
boolean eatt_support,
AttributionSource source) {
- if (!Utils.checkConnectPermissionForDataDelivery(
- this, source, "GattService registerClient")) {
+ if (!checkConnectPermissionForDataDelivery(this, source, TAG, "registerClient")) {
return;
}
if (Flags.gattClientDynamicAllocation()
@@ -1523,8 +1051,7 @@ public class GattService extends ProfileService {
@RequiresPermission(BLUETOOTH_CONNECT)
void unregisterClient(int clientIf, AttributionSource source, ContextMap.RemoveReason reason) {
- if (!Utils.checkConnectPermissionForDataDelivery(
- this, source, "GattService unregisterClient")) {
+ if (!checkConnectPermissionForDataDelivery(this, source, TAG, "unregisterClient")) {
return;
}
@@ -1552,8 +1079,7 @@ public class GattService extends ProfileService {
boolean opportunistic,
int phy,
AttributionSource source) {
- if (!Utils.checkConnectPermissionForDataDelivery(
- this, source, "GattService clientConnect")) {
+ if (!checkConnectPermissionForDataDelivery(this, source, TAG, "clientConnect")) {
return;
}
@@ -1594,9 +1120,11 @@ public class GattService extends ProfileService {
int preferredMtu = 0;
- // Some applications expect MTU to be exchanged immediately on connections
String packageName = source.getPackageName();
if (packageName != null) {
+ mAdapterService.addAssociatedPackage(getDevice(address), packageName);
+
+ // Some apps expect MTU to be exchanged immediately on connections
for (Map.Entry<String, Integer> entry : EARLY_MTU_EXCHANGE_PACKAGES.entrySet()) {
if (packageName.contains(entry.getKey())) {
preferredMtu = entry.getValue();
@@ -1641,8 +1169,7 @@ public class GattService extends ProfileService {
@RequiresPermission(BLUETOOTH_CONNECT)
void clientDisconnect(int clientIf, String address, AttributionSource source) {
- if (!Utils.checkConnectPermissionForDataDelivery(
- this, source, "GattService clientDisconnect")) {
+ if (!checkConnectPermissionForDataDelivery(this, source, TAG, "clientDisconnect")) {
return;
}
@@ -1680,8 +1207,7 @@ public class GattService extends ProfileService {
int rxPhy,
int phyOptions,
AttributionSource source) {
- if (!Utils.checkConnectPermissionForDataDelivery(
- this, source, "GattService clientSetPreferredPhy")) {
+ if (!checkConnectPermissionForDataDelivery(this, source, TAG, "clientSetPreferredPhy")) {
return;
}
@@ -1704,8 +1230,7 @@ public class GattService extends ProfileService {
@RequiresPermission(BLUETOOTH_CONNECT)
void clientReadPhy(int clientIf, String address, AttributionSource source) {
- if (!Utils.checkConnectPermissionForDataDelivery(
- this, source, "GattService clientReadPhy")) {
+ if (!checkConnectPermissionForDataDelivery(this, source, TAG, "clientReadPhy")) {
return;
}
@@ -1723,19 +1248,18 @@ public class GattService extends ProfileService {
@RequiresPermission(BLUETOOTH_CONNECT)
synchronized List<ParcelUuid> getRegisteredServiceUuids(AttributionSource source) {
- if (!Utils.checkConnectPermissionForDataDelivery(
- this, source, "GattService getRegisteredServiceUuids")) {
+ if (!checkConnectPermissionForDataDelivery(
+ this, source, TAG, "getRegisteredServiceUuids")) {
return Collections.emptyList();
}
return mHandleMap.getEntries().stream()
- .map(entry -> new ParcelUuid(entry.uuid))
+ .map(entry -> new ParcelUuid(entry.mUuid))
.collect(Collectors.toList());
}
@RequiresPermission(BLUETOOTH_CONNECT)
List<String> getConnectedDevices(AttributionSource source) {
- if (!Utils.checkConnectPermissionForDataDelivery(
- this, source, "GattService getConnectedDevices")) {
+ if (!checkConnectPermissionForDataDelivery(this, source, TAG, "getConnectedDevices")) {
return Collections.emptyList();
}
@@ -1748,8 +1272,7 @@ public class GattService extends ProfileService {
@RequiresPermission(BLUETOOTH_CONNECT)
void refreshDevice(int clientIf, String address, AttributionSource source) {
- if (!Utils.checkConnectPermissionForDataDelivery(
- this, source, "GattService refreshDevice")) {
+ if (!checkConnectPermissionForDataDelivery(this, source, TAG, "refreshDevice")) {
return;
}
@@ -1759,8 +1282,7 @@ public class GattService extends ProfileService {
@RequiresPermission(BLUETOOTH_CONNECT)
void discoverServices(int clientIf, String address, AttributionSource source) {
- if (!Utils.checkConnectPermissionForDataDelivery(
- this, source, "GattService discoverServices")) {
+ if (!checkConnectPermissionForDataDelivery(this, source, TAG, "discoverServices")) {
return;
}
@@ -1785,8 +1307,7 @@ public class GattService extends ProfileService {
@RequiresPermission(BLUETOOTH_CONNECT)
void discoverServiceByUuid(int clientIf, String address, UUID uuid, AttributionSource source) {
- if (!Utils.checkConnectPermissionForDataDelivery(
- this, source, "GattService discoverServiceByUuid")) {
+ if (!checkConnectPermissionForDataDelivery(this, source, TAG, "discoverServiceByUuid")) {
return;
}
@@ -1806,8 +1327,7 @@ public class GattService extends ProfileService {
@RequiresPermission(BLUETOOTH_CONNECT)
void readCharacteristic(
int clientIf, String address, int handle, int authReq, AttributionSource source) {
- if (!Utils.checkConnectPermissionForDataDelivery(
- this, source, "GattService readCharacteristic")) {
+ if (!checkConnectPermissionForDataDelivery(this, source, TAG, "readCharacteristic")) {
return;
}
@@ -1847,8 +1367,8 @@ public class GattService extends ProfileService {
int endHandle,
int authReq,
AttributionSource source) {
- if (!Utils.checkConnectPermissionForDataDelivery(
- this, source, "GattService readUsingCharacteristicUuid")) {
+ if (!checkConnectPermissionForDataDelivery(
+ this, source, TAG, "readUsingCharacteristicUuid")) {
return;
}
@@ -1894,8 +1414,7 @@ public class GattService extends ProfileService {
int authReq,
byte[] value,
AttributionSource source) {
- if (!Utils.checkConnectPermissionForDataDelivery(
- this, source, "GattService writeCharacteristic")) {
+ if (!checkConnectPermissionForDataDelivery(this, source, TAG, "writeCharacteristic")) {
return BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION;
}
@@ -1940,8 +1459,7 @@ public class GattService extends ProfileService {
@RequiresPermission(BLUETOOTH_CONNECT)
void readDescriptor(
int clientIf, String address, int handle, int authReq, AttributionSource source) {
- if (!Utils.checkConnectPermissionForDataDelivery(
- this, source, "GattService readDescriptor")) {
+ if (!checkConnectPermissionForDataDelivery(this, source, TAG, "readDescriptor")) {
return;
}
@@ -1978,8 +1496,7 @@ public class GattService extends ProfileService {
int authReq,
byte[] value,
AttributionSource source) {
- if (!Utils.checkConnectPermissionForDataDelivery(
- this, source, "GattService writeDescriptor")) {
+ if (!checkConnectPermissionForDataDelivery(this, source, TAG, "writeDescriptor")) {
return BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION;
}
Log.v(TAG, "writeDescriptor() - address=" + toAnonymizedAddress(address));
@@ -2001,8 +1518,7 @@ public class GattService extends ProfileService {
@RequiresPermission(BLUETOOTH_CONNECT)
void beginReliableWrite(int clientIf, String address, AttributionSource source) {
- if (!Utils.checkConnectPermissionForDataDelivery(
- this, source, "GattService beginReliableWrite")) {
+ if (!checkConnectPermissionForDataDelivery(this, source, TAG, "beginReliableWrite")) {
return;
}
@@ -2012,8 +1528,7 @@ public class GattService extends ProfileService {
@RequiresPermission(BLUETOOTH_CONNECT)
void endReliableWrite(int clientIf, String address, boolean execute, AttributionSource source) {
- if (!Utils.checkConnectPermissionForDataDelivery(
- this, source, "GattService endReliableWrite")) {
+ if (!checkConnectPermissionForDataDelivery(this, source, TAG, "endReliableWrite")) {
return;
}
@@ -2034,8 +1549,7 @@ public class GattService extends ProfileService {
@RequiresPermission(BLUETOOTH_CONNECT)
void registerForNotification(
int clientIf, String address, int handle, boolean enable, AttributionSource source) {
- if (!Utils.checkConnectPermissionForDataDelivery(
- this, source, "GattService registerForNotification")) {
+ if (!checkConnectPermissionForDataDelivery(this, source, TAG, "registerForNotification")) {
return;
}
@@ -2073,8 +1587,7 @@ public class GattService extends ProfileService {
@RequiresPermission(BLUETOOTH_CONNECT)
void readRemoteRssi(int clientIf, String address, AttributionSource source) {
- if (!Utils.checkConnectPermissionForDataDelivery(
- this, source, "GattService readRemoteRssi")) {
+ if (!checkConnectPermissionForDataDelivery(this, source, TAG, "readRemoteRssi")) {
return;
}
@@ -2084,8 +1597,7 @@ public class GattService extends ProfileService {
@RequiresPermission(BLUETOOTH_CONNECT)
void configureMTU(int clientIf, String address, int mtu, AttributionSource source) {
- if (!Utils.checkConnectPermissionForDataDelivery(
- this, source, "GattService configureMTU")) {
+ if (!checkConnectPermissionForDataDelivery(this, source, TAG, "configureMTU")) {
return;
}
@@ -2103,8 +1615,8 @@ public class GattService extends ProfileService {
@RequiresPermission(BLUETOOTH_CONNECT)
void connectionParameterUpdate(
int clientIf, String address, int connectionPriority, AttributionSource source) {
- if (!Utils.checkConnectPermissionForDataDelivery(
- this, source, "GattService connectionParameterUpdate")) {
+ if (!checkConnectPermissionForDataDelivery(
+ this, source, TAG, "connectionParameterUpdate")) {
return;
}
@@ -2151,8 +1663,7 @@ public class GattService extends ProfileService {
int minConnectionEventLen,
int maxConnectionEventLen,
AttributionSource source) {
- if (!Utils.checkConnectPermissionForDataDelivery(
- this, source, "GattService leConnectionUpdate")) {
+ if (!checkConnectPermissionForDataDelivery(this, source, TAG, "leConnectionUpdate")) {
return;
}
@@ -2185,7 +1696,7 @@ public class GattService extends ProfileService {
maxConnectionEventLen);
}
- private int subrateModeRequest(int clientIf, BluetoothDevice device, int subrateMode) {
+ int subrateModeRequest(int clientIf, BluetoothDevice device, int subrateMode) {
int subrateMin;
int subrateMax;
int maxLatency;
@@ -2390,7 +1901,7 @@ public class GattService extends ProfileService {
mHandleMap.addRequest(connId, transId, handle);
- ContextMap<IBluetoothGattServerCallback>.App app = mServerMap.getById(entry.serverIf);
+ ContextMap<IBluetoothGattServerCallback>.App app = mServerMap.getById(entry.mServerIf);
if (app == null) {
return;
}
@@ -2423,7 +1934,7 @@ public class GattService extends ProfileService {
mHandleMap.addRequest(connId, transId, handle);
- ContextMap<IBluetoothGattServerCallback>.App app = mServerMap.getById(entry.serverIf);
+ ContextMap<IBluetoothGattServerCallback>.App app = mServerMap.getById(entry.mServerIf);
if (app == null) {
return;
}
@@ -2466,7 +1977,7 @@ public class GattService extends ProfileService {
mHandleMap.addRequest(connId, transId, handle);
- ContextMap<IBluetoothGattServerCallback>.App app = mServerMap.getById(entry.serverIf);
+ ContextMap<IBluetoothGattServerCallback>.App app = mServerMap.getById(entry.mServerIf);
if (app == null) {
return;
}
@@ -2509,7 +2020,7 @@ public class GattService extends ProfileService {
mHandleMap.addRequest(connId, transId, handle);
- ContextMap<IBluetoothGattServerCallback>.App app = mServerMap.getById(entry.serverIf);
+ ContextMap<IBluetoothGattServerCallback>.App app = mServerMap.getById(entry.mServerIf);
if (app == null) {
return;
}
@@ -2613,8 +2124,7 @@ public class GattService extends ProfileService {
IBluetoothGattServerCallback callback,
boolean eatt_support,
AttributionSource source) {
- if (!Utils.checkConnectPermissionForDataDelivery(
- this, source, "GattService registerServer")) {
+ if (!checkConnectPermissionForDataDelivery(this, source, TAG, "registerServer")) {
return;
}
@@ -2626,8 +2136,7 @@ public class GattService extends ProfileService {
@RequiresPermission(BLUETOOTH_CONNECT)
void unregisterServer(int serverIf, AttributionSource source) {
- if (!Utils.checkConnectPermissionForDataDelivery(
- this, source, "GattService unregisterServer")) {
+ if (!checkConnectPermissionForDataDelivery(this, source, TAG, "unregisterServer")) {
return;
}
@@ -2647,8 +2156,7 @@ public class GattService extends ProfileService {
boolean isDirect,
int transport,
AttributionSource source) {
- if (!Utils.checkConnectPermissionForDataDelivery(
- this, source, "GattService serverConnect")) {
+ if (!checkConnectPermissionForDataDelivery(this, source, TAG, "serverConnect")) {
return;
}
@@ -2661,8 +2169,7 @@ public class GattService extends ProfileService {
@RequiresPermission(BLUETOOTH_CONNECT)
void serverDisconnect(int serverIf, String address, AttributionSource source) {
- if (!Utils.checkConnectPermissionForDataDelivery(
- this, source, "GattService serverDisconnect")) {
+ if (!checkConnectPermissionForDataDelivery(this, source, TAG, "serverDisconnect")) {
return;
}
@@ -2685,8 +2192,7 @@ public class GattService extends ProfileService {
int rxPhy,
int phyOptions,
AttributionSource source) {
- if (!Utils.checkConnectPermissionForDataDelivery(
- this, source, "GattService serverSetPreferredPhy")) {
+ if (!checkConnectPermissionForDataDelivery(this, source, TAG, "serverSetPreferredPhy")) {
return;
}
@@ -2709,8 +2215,7 @@ public class GattService extends ProfileService {
@RequiresPermission(BLUETOOTH_CONNECT)
void serverReadPhy(int serverIf, String address, AttributionSource source) {
- if (!Utils.checkConnectPermissionForDataDelivery(
- this, source, "GattService serverReadPhy")) {
+ if (!checkConnectPermissionForDataDelivery(this, source, TAG, "serverReadPhy")) {
return;
}
@@ -2728,7 +2233,7 @@ public class GattService extends ProfileService {
@RequiresPermission(BLUETOOTH_CONNECT)
void addService(int serverIf, BluetoothGattService service, AttributionSource source) {
- if (!Utils.checkConnectPermissionForDataDelivery(this, source, "GattService addService")) {
+ if (!checkConnectPermissionForDataDelivery(this, source, TAG, "addService")) {
return;
}
@@ -2773,8 +2278,7 @@ public class GattService extends ProfileService {
@RequiresPermission(BLUETOOTH_CONNECT)
void removeService(int serverIf, int handle, AttributionSource source) {
- if (!Utils.checkConnectPermissionForDataDelivery(
- this, source, "GattService removeService")) {
+ if (!checkConnectPermissionForDataDelivery(this, source, TAG, "removeService")) {
return;
}
@@ -2785,8 +2289,7 @@ public class GattService extends ProfileService {
@RequiresPermission(BLUETOOTH_CONNECT)
void clearServices(int serverIf, AttributionSource source) {
- if (!Utils.checkConnectPermissionForDataDelivery(
- this, source, "GattService clearServices")) {
+ if (!checkConnectPermissionForDataDelivery(this, source, TAG, "clearServices")) {
return;
}
@@ -2803,8 +2306,7 @@ public class GattService extends ProfileService {
int offset,
byte[] value,
AttributionSource source) {
- if (!Utils.checkConnectPermissionForDataDelivery(
- this, source, "GattService sendResponse")) {
+ if (!checkConnectPermissionForDataDelivery(this, source, TAG, "sendResponse")) {
return;
}
@@ -2821,14 +2323,14 @@ public class GattService extends ProfileService {
if (!Flags.gattServerRequestsFix()) {
HandleMap.Entry entry = mHandleMap.getByRequestId(requestId);
if (entry != null) {
- handle = entry.handle;
+ handle = entry.mHandle;
}
connId = mServerMap.connIdByAddress(serverIf, address);
} else {
HandleMap.RequestData requestData = mHandleMap.getRequestDataByRequestId(requestId);
if (requestData != null) {
- handle = requestData.mHandle;
- connId = requestData.mConnId;
+ handle = requestData.handle();
+ connId = requestData.connId();
} else {
connId = mServerMap.connIdByAddress(serverIf, address);
}
@@ -2853,8 +2355,7 @@ public class GattService extends ProfileService {
boolean confirm,
byte[] value,
AttributionSource source) {
- if (!Utils.checkConnectPermissionForDataDelivery(
- this, source, "GattService sendNotification")) {
+ if (!checkConnectPermissionForDataDelivery(this, source, TAG, "sendNotification")) {
return BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION;
}
@@ -2998,13 +2499,13 @@ public class GattService extends ProfileService {
}
List<HandleMap.Entry> entries = mHandleMap.getEntries();
for (HandleMap.Entry entry : entries) {
- if (entry.type != HandleMap.TYPE_SERVICE
- || entry.serverIf != serverIf
- || !entry.started) {
+ if (entry.mType != HandleMap.TYPE_SERVICE
+ || entry.mServerIf != serverIf
+ || !entry.mStarted) {
continue;
}
- mNativeInterface.gattServerStopService(serverIf, entry.handle);
+ mNativeInterface.gattServerStopService(serverIf, entry.mHandle);
return;
}
}
@@ -3019,10 +2520,10 @@ public class GattService extends ProfileService {
List<Integer> handleList = new ArrayList<>();
List<HandleMap.Entry> entries = mHandleMap.getEntries();
for (HandleMap.Entry entry : entries) {
- if (entry.type != HandleMap.TYPE_SERVICE || entry.serverIf != serverIf) {
+ if (entry.mType != HandleMap.TYPE_SERVICE || entry.mServerIf != serverIf) {
continue;
}
- handleList.add(entry.handle);
+ handleList.add(entry.mHandle);
}
/* Now actually delete the services.... */
@@ -3126,13 +2627,6 @@ public class GattService extends ProfileService {
+ connectionStatus);
}
- @Override
- public void dumpProto(BluetoothMetricsProto.BluetoothLog.Builder builder) {
- if (mScanController != null) {
- mScanController.dumpProto(builder);
- }
- }
-
private BluetoothDevice getDevice(String address) {
byte[] addressBytes = Utils.getBytesFromAddress(address);
return mAdapterService.getDeviceFromByte(addressBytes);
diff --git a/android/app/src/com/android/bluetooth/gatt/GattServiceBinder.java b/android/app/src/com/android/bluetooth/gatt/GattServiceBinder.java
new file mode 100644
index 0000000000..7be287677c
--- /dev/null
+++ b/android/app/src/com/android/bluetooth/gatt/GattServiceBinder.java
@@ -0,0 +1,499 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.bluetooth.gatt;
+
+import static com.android.bluetooth.Utils.callerIsSystemOrActiveOrManagedUser;
+import static com.android.bluetooth.Utils.checkConnectPermissionForDataDelivery;
+
+import static java.util.Objects.requireNonNull;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothGatt;
+import android.bluetooth.BluetoothGattService;
+import android.bluetooth.BluetoothStatusCodes;
+import android.bluetooth.IBluetoothGatt;
+import android.bluetooth.IBluetoothGattCallback;
+import android.bluetooth.IBluetoothGattServerCallback;
+import android.content.AttributionSource;
+import android.os.ParcelUuid;
+
+import com.android.bluetooth.Utils;
+import com.android.bluetooth.btservice.ProfileService.IProfileServiceBinder;
+
+import java.util.Collections;
+import java.util.List;
+
+/** Handlers for incoming service calls */
+class GattServiceBinder extends IBluetoothGatt.Stub implements IProfileServiceBinder {
+ private static final String TAG =
+ GattServiceConfig.TAG_PREFIX + GattServiceBinder.class.getSimpleName();
+
+ private GattService mService;
+
+ GattServiceBinder(GattService svc) {
+ mService = svc;
+ }
+
+ @Override
+ public void cleanup() {
+ mService = null;
+ }
+
+ private GattService getService() {
+ GattService service = mService;
+
+ if (!Utils.checkServiceAvailable(service, TAG)) {
+ return null;
+ }
+
+ return service;
+ }
+
+ @Override
+ public List<BluetoothDevice> getDevicesMatchingConnectionStates(
+ int[] states, AttributionSource source) {
+ GattService service = getService();
+ if (service == null) {
+ return Collections.emptyList();
+ }
+ return service.getDevicesMatchingConnectionStates(states, source);
+ }
+
+ @Override
+ public void registerClient(
+ ParcelUuid uuid,
+ IBluetoothGattCallback callback,
+ boolean eattSupport,
+ AttributionSource source) {
+ GattService service = getService();
+ if (service == null) {
+ return;
+ }
+ service.registerClient(uuid.getUuid(), callback, eattSupport, source);
+ }
+
+ @Override
+ public void unregisterClient(int clientIf, AttributionSource source) {
+ GattService service = getService();
+ if (service == null) {
+ return;
+ }
+ service.unregisterClient(
+ clientIf, source, ContextMap.RemoveReason.REASON_UNREGISTER_CLIENT);
+ }
+
+ @Override
+ public void clientConnect(
+ int clientIf,
+ String address,
+ int addressType,
+ boolean isDirect,
+ int transport,
+ boolean opportunistic,
+ int phy,
+ AttributionSource source) {
+ GattService service = getService();
+ if (service == null) {
+ return;
+ }
+ service.clientConnect(
+ clientIf, address, addressType, isDirect, transport, opportunistic, phy, source);
+ }
+
+ @Override
+ public void clientDisconnect(int clientIf, String address, AttributionSource source) {
+ GattService service = getService();
+ if (service == null) {
+ return;
+ }
+ service.clientDisconnect(clientIf, address, source);
+ }
+
+ @Override
+ public void clientSetPreferredPhy(
+ int clientIf,
+ String address,
+ int txPhy,
+ int rxPhy,
+ int phyOptions,
+ AttributionSource source) {
+ GattService service = getService();
+ if (service == null) {
+ return;
+ }
+ service.clientSetPreferredPhy(clientIf, address, txPhy, rxPhy, phyOptions, source);
+ }
+
+ @Override
+ public void clientReadPhy(int clientIf, String address, AttributionSource source) {
+ GattService service = getService();
+ if (service == null) {
+ return;
+ }
+ service.clientReadPhy(clientIf, address, source);
+ }
+
+ @Override
+ public void refreshDevice(int clientIf, String address, AttributionSource source) {
+ GattService service = getService();
+ if (service == null) {
+ return;
+ }
+ service.refreshDevice(clientIf, address, source);
+ }
+
+ @Override
+ public void discoverServices(int clientIf, String address, AttributionSource source) {
+ GattService service = getService();
+ if (service == null) {
+ return;
+ }
+ service.discoverServices(clientIf, address, source);
+ }
+
+ @Override
+ public void discoverServiceByUuid(
+ int clientIf, String address, ParcelUuid uuid, AttributionSource source) {
+ GattService service = getService();
+ if (service == null) {
+ return;
+ }
+ service.discoverServiceByUuid(clientIf, address, uuid.getUuid(), source);
+ }
+
+ @Override
+ public void readCharacteristic(
+ int clientIf, String address, int handle, int authReq, AttributionSource source) {
+ GattService service = getService();
+ if (service == null) {
+ return;
+ }
+ service.readCharacteristic(clientIf, address, handle, authReq, source);
+ }
+
+ @Override
+ public void readUsingCharacteristicUuid(
+ int clientIf,
+ String address,
+ ParcelUuid uuid,
+ int startHandle,
+ int endHandle,
+ int authReq,
+ AttributionSource source) {
+ GattService service = getService();
+ if (service == null) {
+ return;
+ }
+ service.readUsingCharacteristicUuid(
+ clientIf, address, uuid.getUuid(), startHandle, endHandle, authReq, source);
+ }
+
+ @Override
+ public int writeCharacteristic(
+ int clientIf,
+ String address,
+ int handle,
+ int writeType,
+ int authReq,
+ byte[] value,
+ AttributionSource source) {
+ GattService service = getService();
+ if (service == null) {
+ return BluetoothStatusCodes.ERROR_PROFILE_SERVICE_NOT_BOUND;
+ }
+ return service.writeCharacteristic(
+ clientIf, address, handle, writeType, authReq, value, source);
+ }
+
+ @Override
+ public void readDescriptor(
+ int clientIf, String address, int handle, int authReq, AttributionSource source) {
+ GattService service = getService();
+ if (service == null) {
+ return;
+ }
+ service.readDescriptor(clientIf, address, handle, authReq, source);
+ }
+
+ @Override
+ public int writeDescriptor(
+ int clientIf,
+ String address,
+ int handle,
+ int authReq,
+ byte[] value,
+ AttributionSource source) {
+ GattService service = getService();
+ if (service == null) {
+ return BluetoothStatusCodes.ERROR_PROFILE_SERVICE_NOT_BOUND;
+ }
+ return service.writeDescriptor(clientIf, address, handle, authReq, value, source);
+ }
+
+ @Override
+ public void beginReliableWrite(int clientIf, String address, AttributionSource source) {
+ GattService service = getService();
+ if (service == null) {
+ return;
+ }
+ service.beginReliableWrite(clientIf, address, source);
+ }
+
+ @Override
+ public void endReliableWrite(
+ int clientIf, String address, boolean execute, AttributionSource source) {
+ GattService service = getService();
+ if (service == null) {
+ return;
+ }
+ service.endReliableWrite(clientIf, address, execute, source);
+ }
+
+ @Override
+ public void registerForNotification(
+ int clientIf, String address, int handle, boolean enable, AttributionSource source) {
+ GattService service = getService();
+ if (service == null) {
+ return;
+ }
+ service.registerForNotification(clientIf, address, handle, enable, source);
+ }
+
+ @Override
+ public void readRemoteRssi(int clientIf, String address, AttributionSource source) {
+ GattService service = getService();
+ if (service == null) {
+ return;
+ }
+ service.readRemoteRssi(clientIf, address, source);
+ }
+
+ @Override
+ public void configureMTU(int clientIf, String address, int mtu, AttributionSource source) {
+ GattService service = getService();
+ if (service == null) {
+ return;
+ }
+ service.configureMTU(clientIf, address, mtu, source);
+ }
+
+ @Override
+ public void connectionParameterUpdate(
+ int clientIf, String address, int connectionPriority, AttributionSource source) {
+ GattService service = getService();
+ if (service == null) {
+ return;
+ }
+ service.connectionParameterUpdate(clientIf, address, connectionPriority, source);
+ }
+
+ @Override
+ public void leConnectionUpdate(
+ int clientIf,
+ String address,
+ int minConnectionInterval,
+ int maxConnectionInterval,
+ int peripheralLatency,
+ int supervisionTimeout,
+ int minConnectionEventLen,
+ int maxConnectionEventLen,
+ AttributionSource source) {
+ GattService service = getService();
+ if (service == null) {
+ return;
+ }
+ service.leConnectionUpdate(
+ clientIf,
+ address,
+ minConnectionInterval,
+ maxConnectionInterval,
+ peripheralLatency,
+ supervisionTimeout,
+ minConnectionEventLen,
+ maxConnectionEventLen,
+ source);
+ }
+
+ @Override
+ public int subrateModeRequest(
+ int clientIf, BluetoothDevice device, int subrateMode, AttributionSource source) {
+ GattService service = getService();
+ if (service == null) {
+ return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED;
+ }
+ if (!callerIsSystemOrActiveOrManagedUser(service, TAG, "subrateModeRequest")) {
+ return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ALLOWED;
+ }
+ if (!checkConnectPermissionForDataDelivery(service, source, TAG, "subrateModeRequest")) {
+ return BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION;
+ }
+
+ Utils.enforceCdmAssociationIfNotBluetoothPrivileged(
+ service, service.getCompanionDeviceManager(), source, device);
+
+ if (subrateMode < BluetoothGatt.SUBRATE_REQUEST_MODE_BALANCED
+ || subrateMode > BluetoothGatt.SUBRATE_REQUEST_MODE_LOW_POWER) {
+ throw new IllegalArgumentException("Subrate Mode not within valid range");
+ }
+
+ requireNonNull(device);
+ String address = device.getAddress();
+ if (!BluetoothAdapter.checkBluetoothAddress(address)) {
+ throw new IllegalArgumentException("Invalid device address: " + address);
+ }
+
+ return service.subrateModeRequest(clientIf, device, subrateMode);
+ }
+
+ @Override
+ public void registerServer(
+ ParcelUuid uuid,
+ IBluetoothGattServerCallback callback,
+ boolean eattSupport,
+ AttributionSource source) {
+ GattService service = getService();
+ if (service == null) {
+ return;
+ }
+ service.registerServer(uuid.getUuid(), callback, eattSupport, source);
+ }
+
+ @Override
+ public void unregisterServer(int serverIf, AttributionSource source) {
+ GattService service = getService();
+ if (service == null) {
+ return;
+ }
+ service.unregisterServer(serverIf, source);
+ }
+
+ @Override
+ public void serverConnect(
+ int serverIf,
+ String address,
+ int addressType,
+ boolean isDirect,
+ int transport,
+ AttributionSource source) {
+ GattService service = getService();
+ if (service == null) {
+ return;
+ }
+ service.serverConnect(serverIf, address, addressType, isDirect, transport, source);
+ }
+
+ @Override
+ public void serverDisconnect(int serverIf, String address, AttributionSource source) {
+ GattService service = getService();
+ if (service == null) {
+ return;
+ }
+ service.serverDisconnect(serverIf, address, source);
+ }
+
+ @Override
+ public void serverSetPreferredPhy(
+ int serverIf,
+ String address,
+ int txPhy,
+ int rxPhy,
+ int phyOptions,
+ AttributionSource source) {
+ GattService service = getService();
+ if (service == null) {
+ return;
+ }
+ service.serverSetPreferredPhy(serverIf, address, txPhy, rxPhy, phyOptions, source);
+ }
+
+ @Override
+ public void serverReadPhy(int clientIf, String address, AttributionSource source) {
+ GattService service = getService();
+ if (service == null) {
+ return;
+ }
+ service.serverReadPhy(clientIf, address, source);
+ }
+
+ @Override
+ public void addService(int serverIf, BluetoothGattService svc, AttributionSource source) {
+ GattService service = getService();
+ if (service == null) {
+ return;
+ }
+ service.addService(serverIf, svc, source);
+ }
+
+ @Override
+ public void removeService(int serverIf, int handle, AttributionSource source) {
+ GattService service = getService();
+ if (service == null) {
+ return;
+ }
+ service.removeService(serverIf, handle, source);
+ }
+
+ @Override
+ public void clearServices(int serverIf, AttributionSource source) {
+ GattService service = getService();
+ if (service == null) {
+ return;
+ }
+ service.clearServices(serverIf, source);
+ }
+
+ @Override
+ public void sendResponse(
+ int serverIf,
+ String address,
+ int requestId,
+ int status,
+ int offset,
+ byte[] value,
+ AttributionSource source) {
+ GattService service = getService();
+ if (service == null) {
+ return;
+ }
+ service.sendResponse(serverIf, address, requestId, status, offset, value, source);
+ }
+
+ @Override
+ public int sendNotification(
+ int serverIf,
+ String address,
+ int handle,
+ boolean confirm,
+ byte[] value,
+ AttributionSource source) {
+ GattService service = getService();
+ if (service == null) {
+ return BluetoothStatusCodes.ERROR_PROFILE_SERVICE_NOT_BOUND;
+ }
+ return service.sendNotification(serverIf, address, handle, confirm, value, source);
+ }
+
+ @Override
+ public void disconnectAll(AttributionSource source) {
+ GattService service = getService();
+ if (service == null) {
+ return;
+ }
+ service.disconnectAll(source);
+ }
+}
diff --git a/android/app/src/com/android/bluetooth/gatt/HandleMap.java b/android/app/src/com/android/bluetooth/gatt/HandleMap.java
index 8e0ce8023e..dde3a56e1c 100644
--- a/android/app/src/com/android/bluetooth/gatt/HandleMap.java
+++ b/android/app/src/com/android/bluetooth/gatt/HandleMap.java
@@ -27,30 +27,38 @@ class HandleMap {
private static final String TAG =
GattServiceConfig.TAG_PREFIX + HandleMap.class.getSimpleName();
- public static final int TYPE_UNDEFINED = 0;
- public static final int TYPE_SERVICE = 1;
- public static final int TYPE_CHARACTERISTIC = 2;
- public static final int TYPE_DESCRIPTOR = 3;
+ static final int TYPE_SERVICE = 1;
+ private static final int TYPE_CHARACTERISTIC = 2;
+ private static final int TYPE_DESCRIPTOR = 3;
+
+ private final List<Entry> mEntries = new CopyOnWriteArrayList<>();
+ private final Map<Integer, RequestData> mRequestMap = new ConcurrentHashMap<>();
+ private int mLastCharacteristic = 0;
+
+ void clear() {
+ mEntries.clear();
+ mRequestMap.clear();
+ }
static class Entry {
- public int serverIf = 0;
- public int type = TYPE_UNDEFINED;
- public int handle = 0;
- public UUID uuid = null;
- public int instance = 0;
- public int serviceType = 0;
- public int serviceHandle = 0;
- public int charHandle = 0;
- public boolean started = false;
- public boolean advertisePreferred = false;
+ final int mServerIf;
+ final int mType;
+ final int mHandle;
+ final UUID mUuid;
+ int mInstance = 0;
+ int mServiceType = 0;
+ int mServiceHandle = 0;
+ int mCharHandle = 0;
+ boolean mAdvertisePreferred = false;
+ boolean mStarted = false;
Entry(int serverIf, int handle, UUID uuid, int serviceType, int instance) {
- this.serverIf = serverIf;
- this.type = TYPE_SERVICE;
- this.handle = handle;
- this.uuid = uuid;
- this.instance = instance;
- this.serviceType = serviceType;
+ mServerIf = serverIf;
+ mType = TYPE_SERVICE;
+ mHandle = handle;
+ mUuid = uuid;
+ mInstance = instance;
+ mServiceType = serviceType;
}
Entry(
@@ -60,55 +68,37 @@ class HandleMap {
int serviceType,
int instance,
boolean advertisePreferred) {
- this.serverIf = serverIf;
- this.type = TYPE_SERVICE;
- this.handle = handle;
- this.uuid = uuid;
- this.instance = instance;
- this.serviceType = serviceType;
- this.advertisePreferred = advertisePreferred;
+ mServerIf = serverIf;
+ mType = TYPE_SERVICE;
+ mHandle = handle;
+ mUuid = uuid;
+ mInstance = instance;
+ mServiceType = serviceType;
+ mAdvertisePreferred = advertisePreferred;
}
Entry(int serverIf, int type, int handle, UUID uuid, int serviceHandle) {
- this.serverIf = serverIf;
- this.type = type;
- this.handle = handle;
- this.uuid = uuid;
- this.serviceHandle = serviceHandle;
+ mServerIf = serverIf;
+ mType = type;
+ mHandle = handle;
+ mUuid = uuid;
+ mServiceHandle = serviceHandle;
}
Entry(int serverIf, int type, int handle, UUID uuid, int serviceHandle, int charHandle) {
- this.serverIf = serverIf;
- this.type = type;
- this.handle = handle;
- this.uuid = uuid;
- this.serviceHandle = serviceHandle;
- this.charHandle = charHandle;
- }
- }
-
- static class RequestData {
- int mConnId;
- int mHandle;
-
- RequestData(int connId, int handle) {
- mConnId = connId;
+ mServerIf = serverIf;
+ mType = type;
mHandle = handle;
+ mUuid = uuid;
+ mServiceHandle = serviceHandle;
+ mCharHandle = charHandle;
}
}
- List<Entry> mEntries = null;
- Map<Integer, RequestData> mRequestMap = null;
- int mLastCharacteristic = 0;
+ record RequestData(int connId, int handle) {}
- HandleMap() {
- mEntries = new CopyOnWriteArrayList<Entry>();
- mRequestMap = new ConcurrentHashMap<Integer, RequestData>();
- }
-
- void clear() {
- mEntries.clear();
- mRequestMap.clear();
+ List<Entry> getEntries() {
+ return mEntries;
}
void addService(
@@ -139,20 +129,20 @@ class HandleMap {
void setStarted(int serverIf, int handle, boolean started) {
for (Entry entry : mEntries) {
- if (entry.type != TYPE_SERVICE
- || entry.serverIf != serverIf
- || entry.handle != handle) {
+ if (entry.mType != TYPE_SERVICE
+ || entry.mServerIf != serverIf
+ || entry.mHandle != handle) {
continue;
}
- entry.started = started;
+ entry.mStarted = started;
return;
}
}
Entry getByHandle(int handle) {
for (Entry entry : mEntries) {
- if (entry.handle == handle) {
+ if (entry.mHandle == handle) {
return entry;
}
}
@@ -162,7 +152,9 @@ class HandleMap {
boolean checkServiceExists(UUID uuid, int handle) {
for (Entry entry : mEntries) {
- if (entry.type == TYPE_SERVICE && entry.handle == handle && entry.uuid.equals(uuid)) {
+ if (entry.mType == TYPE_SERVICE
+ && entry.mHandle == handle
+ && entry.mUuid.equals(uuid)) {
return true;
}
}
@@ -172,13 +164,9 @@ class HandleMap {
void deleteService(int serverIf, int serviceHandle) {
mEntries.removeIf(
entry ->
- ((entry.serverIf == serverIf)
- && (entry.handle == serviceHandle
- || entry.serviceHandle == serviceHandle)));
- }
-
- List<Entry> getEntries() {
- return mEntries;
+ ((entry.mServerIf == serverIf)
+ && (entry.mHandle == serviceHandle
+ || entry.mServiceHandle == serviceHandle)));
}
void addRequest(int connId, int requestId, int handle) {
@@ -193,7 +181,7 @@ class HandleMap {
Integer handle = null;
RequestData data = mRequestMap.get(requestId);
if (data != null) {
- handle = data.mHandle;
+ handle = data.handle;
}
if (handle == null) {
@@ -211,7 +199,7 @@ class HandleMap {
Log.d(
TAG,
("getRequestDataByRequestId(), requestId=" + requestId)
- + (", connId=" + data.mConnId + ",handle=" + data.mHandle));
+ + (", connId=" + data.connId + ",handle=" + data.handle));
}
return data;
@@ -223,22 +211,23 @@ class HandleMap {
sb.append(" Requests: ").append(mRequestMap.size()).append("\n");
for (Entry entry : mEntries) {
- sb.append(" ").append(entry.serverIf).append(": [").append(entry.handle).append("] ");
- switch (entry.type) {
+ sb.append(" ")
+ .append(entry.mServerIf)
+ .append(": [")
+ .append(entry.mHandle)
+ .append("] ");
+ switch (entry.mType) {
case TYPE_SERVICE:
- sb.append("Service ").append(entry.uuid);
- sb.append(", started ").append(entry.started);
+ sb.append("Service ").append(entry.mUuid);
+ sb.append(", started ").append(entry.mStarted);
break;
-
case TYPE_CHARACTERISTIC:
- sb.append(" Characteristic ").append(entry.uuid);
+ sb.append(" Characteristic ").append(entry.mUuid);
break;
-
case TYPE_DESCRIPTOR:
- sb.append(" Descriptor ").append(entry.uuid);
+ sb.append(" Descriptor ").append(entry.mUuid);
break;
}
-
sb.append("\n");
}
}
diff --git a/android/app/src/com/android/bluetooth/hap/HapClientNativeCallback.java b/android/app/src/com/android/bluetooth/hap/HapClientNativeCallback.java
index 3fef07078d..5dcc0d7ed0 100644
--- a/android/app/src/com/android/bluetooth/hap/HapClientNativeCallback.java
+++ b/android/app/src/com/android/bluetooth/hap/HapClientNativeCallback.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 The Android Open Source Project
+ * Copyright (C) 2024 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.
diff --git a/android/app/src/com/android/bluetooth/hap/HapClientService.java b/android/app/src/com/android/bluetooth/hap/HapClientService.java
index 731f3da90c..9b8092763c 100644
--- a/android/app/src/com/android/bluetooth/hap/HapClientService.java
+++ b/android/app/src/com/android/bluetooth/hap/HapClientService.java
@@ -159,7 +159,7 @@ public class HapClientService extends ProfileService {
@Override
protected IProfileServiceBinder initBinder() {
- return new HapClientBinder(this);
+ return new HapClientServiceBinder(this);
}
@Override
diff --git a/android/app/src/com/android/bluetooth/hap/HapClientBinder.java b/android/app/src/com/android/bluetooth/hap/HapClientServiceBinder.java
index 97bd4e9f9e..e036e43bb2 100644
--- a/android/app/src/com/android/bluetooth/hap/HapClientBinder.java
+++ b/android/app/src/com/android/bluetooth/hap/HapClientServiceBinder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 The Android Open Source Project
+ * Copyright (C) 2024 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.
@@ -36,21 +36,19 @@ import android.content.AttributionSource;
import android.util.Log;
import com.android.bluetooth.Utils;
-import com.android.bluetooth.btservice.ProfileService;
+import com.android.bluetooth.btservice.ProfileService.IProfileServiceBinder;
import com.android.internal.annotations.VisibleForTesting;
import java.util.Collections;
import java.util.List;
-/** HapClientBinder class */
@VisibleForTesting
-class HapClientBinder extends IBluetoothHapClient.Stub
- implements ProfileService.IProfileServiceBinder {
- private static final String TAG = HapClientBinder.class.getSimpleName();
+class HapClientServiceBinder extends IBluetoothHapClient.Stub implements IProfileServiceBinder {
+ private static final String TAG = HapClientServiceBinder.class.getSimpleName();
private HapClientService mService;
- HapClientBinder(HapClientService svc) {
+ HapClientServiceBinder(HapClientService svc) {
mService = svc;
}
@@ -62,7 +60,6 @@ class HapClientBinder extends IBluetoothHapClient.Stub
@RequiresPermission(allOf = {BLUETOOTH_CONNECT, BLUETOOTH_PRIVILEGED})
private HapClientService getService(AttributionSource source) {
requireNonNull(source);
- // Cache mService because it can change while getService is called
HapClientService service = mService;
if (Utils.isInstrumentationTestMode()) {
@@ -86,7 +83,6 @@ class HapClientBinder extends IBluetoothHapClient.Stub
if (service == null) {
return Collections.emptyList();
}
-
return service.getConnectedDevices();
}
@@ -97,7 +93,6 @@ class HapClientBinder extends IBluetoothHapClient.Stub
if (service == null) {
return Collections.emptyList();
}
-
return service.getDevicesMatchingConnectionStates(states);
}
@@ -109,7 +104,6 @@ class HapClientBinder extends IBluetoothHapClient.Stub
}
requireNonNull(device);
-
return service.getConnectionState(device);
}
@@ -139,7 +133,6 @@ class HapClientBinder extends IBluetoothHapClient.Stub
}
requireNonNull(device);
-
return service.getConnectionPolicy(device);
}
@@ -151,7 +144,6 @@ class HapClientBinder extends IBluetoothHapClient.Stub
}
requireNonNull(device);
-
return service.getActivePresetIndex(device);
}
@@ -164,7 +156,6 @@ class HapClientBinder extends IBluetoothHapClient.Stub
}
requireNonNull(device);
-
return service.getActivePresetInfo(device);
}
@@ -176,7 +167,6 @@ class HapClientBinder extends IBluetoothHapClient.Stub
}
requireNonNull(device);
-
return service.getHapGroup(device);
}
@@ -188,7 +178,6 @@ class HapClientBinder extends IBluetoothHapClient.Stub
}
requireNonNull(device);
-
service.selectPreset(device, presetIndex);
}
@@ -198,7 +187,6 @@ class HapClientBinder extends IBluetoothHapClient.Stub
if (service == null) {
return;
}
-
service.selectPresetForGroup(groupId, presetIndex);
}
@@ -210,7 +198,6 @@ class HapClientBinder extends IBluetoothHapClient.Stub
}
requireNonNull(device);
-
service.switchToNextPreset(device);
}
@@ -220,7 +207,6 @@ class HapClientBinder extends IBluetoothHapClient.Stub
if (service == null) {
return;
}
-
service.switchToNextPresetForGroup(groupId);
}
@@ -232,7 +218,6 @@ class HapClientBinder extends IBluetoothHapClient.Stub
}
requireNonNull(device);
-
service.switchToPreviousPreset(device);
}
@@ -242,7 +227,6 @@ class HapClientBinder extends IBluetoothHapClient.Stub
if (service == null) {
return;
}
-
service.switchToPreviousPresetForGroup(groupId);
}
@@ -255,7 +239,6 @@ class HapClientBinder extends IBluetoothHapClient.Stub
}
requireNonNull(device);
-
return service.getPresetInfo(device, presetIndex);
}
@@ -268,7 +251,6 @@ class HapClientBinder extends IBluetoothHapClient.Stub
}
requireNonNull(device);
-
return service.getAllPresetInfo(device);
}
@@ -280,7 +262,6 @@ class HapClientBinder extends IBluetoothHapClient.Stub
}
requireNonNull(device);
-
return service.getFeatures(device);
}
@@ -294,7 +275,6 @@ class HapClientBinder extends IBluetoothHapClient.Stub
requireNonNull(device);
requireNonNull(name);
-
service.setPresetName(device, presetIndex, name);
}
@@ -307,7 +287,6 @@ class HapClientBinder extends IBluetoothHapClient.Stub
}
requireNonNull(name);
-
service.setPresetNameForGroup(groupId, presetIndex, name);
}
@@ -319,7 +298,6 @@ class HapClientBinder extends IBluetoothHapClient.Stub
}
requireNonNull(callback);
-
service.registerCallback(callback);
}
@@ -331,7 +309,6 @@ class HapClientBinder extends IBluetoothHapClient.Stub
}
requireNonNull(callback);
-
service.unregisterCallback(callback);
}
}
diff --git a/android/app/src/com/android/bluetooth/hearingaid/HearingAidNativeInterface.java b/android/app/src/com/android/bluetooth/hearingaid/HearingAidNativeInterface.java
index 23ad690a21..31761db66d 100644
--- a/android/app/src/com/android/bluetooth/hearingaid/HearingAidNativeInterface.java
+++ b/android/app/src/com/android/bluetooth/hearingaid/HearingAidNativeInterface.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 The Android Open Source Project
+ * Copyright (C) 2018 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.
diff --git a/android/app/src/com/android/bluetooth/hearingaid/HearingAidService.java b/android/app/src/com/android/bluetooth/hearingaid/HearingAidService.java
index 88f158a0ed..0bf2650bb1 100644
--- a/android/app/src/com/android/bluetooth/hearingaid/HearingAidService.java
+++ b/android/app/src/com/android/bluetooth/hearingaid/HearingAidService.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 The Android Open Source Project
+ * Copyright (C) 2018 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.
@@ -17,7 +17,6 @@
package com.android.bluetooth.hearingaid;
import static android.Manifest.permission.BLUETOOTH_CONNECT;
-import static android.Manifest.permission.BLUETOOTH_PRIVILEGED;
import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_ALLOWED;
import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_UNKNOWN;
@@ -27,14 +26,11 @@ import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTED;
import static java.util.Objects.requireNonNull;
-import android.annotation.RequiresPermission;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHearingAid;
import android.bluetooth.BluetoothHearingAid.AdvertisementServiceData;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothUuid;
-import android.bluetooth.IBluetoothHearingAid;
-import android.content.AttributionSource;
import android.content.Intent;
import android.media.AudioDeviceCallback;
import android.media.AudioDeviceInfo;
@@ -48,18 +44,15 @@ import android.os.UserHandle;
import android.sysprop.BluetoothProperties;
import android.util.Log;
-import com.android.bluetooth.BluetoothMetricsProto;
import com.android.bluetooth.BluetoothStatsLog;
import com.android.bluetooth.Utils;
import com.android.bluetooth.btservice.AdapterService;
-import com.android.bluetooth.btservice.MetricsLogger;
import com.android.bluetooth.btservice.ProfileService;
import com.android.bluetooth.btservice.storage.DatabaseManager;
import com.android.bluetooth.flags.Flags;
import com.android.internal.annotations.VisibleForTesting;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -132,7 +125,7 @@ public class HearingAidService extends ProfileService {
@Override
protected IProfileServiceBinder initBinder() {
- return new BluetoothHearingAidBinder(this);
+ return new HearingAidServiceBinder(this);
}
@Override
@@ -492,7 +485,7 @@ public class HearingAidService extends ProfileService {
return mDeviceCapabilitiesMap.getOrDefault(device, -1);
}
- private AdvertisementServiceData getAdvertisementServiceData(BluetoothDevice device) {
+ AdvertisementServiceData getAdvertisementServiceData(BluetoothDevice device) {
int capability = mAdapterService.getAshaCapability(device);
int id = mAdapterService.getAshaTruncatedHiSyncId(device);
if (capability < 0) {
@@ -830,13 +823,6 @@ public class HearingAidService extends ProfileService {
}
if (toState == STATE_CONNECTED) {
long myHiSyncId = getHiSyncId(device);
- if (myHiSyncId == BluetoothHearingAid.HI_SYNC_ID_INVALID
- || getConnectedPeerDevices(myHiSyncId).size() == 1) {
- // Log hearing aid connection event if we are the first device in a set
- // Or when the hiSyncId has not been found
- MetricsLogger.logProfileConnectionEvent(
- BluetoothMetricsProto.ProfileId.HEARING_AID);
- }
if (!mHiSyncIdConnectedMap.getOrDefault(myHiSyncId, false)) {
mHiSyncIdConnectedMap.put(myHiSyncId, true);
}
@@ -864,213 +850,6 @@ public class HearingAidService extends ProfileService {
device, BluetoothProfile.HEARING_AID, toState, fromState);
}
- /** Binder object: must be a static class or memory leak may occur */
- @VisibleForTesting
- static class BluetoothHearingAidBinder extends IBluetoothHearingAid.Stub
- implements IProfileServiceBinder {
- private HearingAidService mService;
-
- BluetoothHearingAidBinder(HearingAidService svc) {
- mService = svc;
- }
-
- @Override
- public void cleanup() {
- mService = null;
- }
-
- @RequiresPermission(BLUETOOTH_CONNECT)
- private HearingAidService getService(AttributionSource source) {
- // Cache mService because it can change while getService is called
- HearingAidService service = mService;
-
- if (Utils.isInstrumentationTestMode()) {
- return service;
- }
-
- if (!Utils.checkServiceAvailable(service, TAG)
- || !Utils.checkCallerIsSystemOrActiveOrManagedUser(service, TAG)
- || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
- return null;
- }
- return service;
- }
-
- @Override
- public boolean connect(BluetoothDevice device, AttributionSource source) {
- HearingAidService service = getService(source);
- if (service == null) {
- return false;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- return service.connect(device);
- }
-
- @Override
- public boolean disconnect(BluetoothDevice device, AttributionSource source) {
- HearingAidService service = getService(source);
- if (service == null) {
- return false;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- return service.disconnect(device);
- }
-
- @Override
- public List<BluetoothDevice> getConnectedDevices(AttributionSource source) {
- HearingAidService service = getService(source);
- if (service == null) {
- return Collections.emptyList();
- }
-
- return service.getConnectedDevices();
- }
-
- @Override
- public List<BluetoothDevice> getDevicesMatchingConnectionStates(
- int[] states, AttributionSource source) {
- HearingAidService service = getService(source);
- if (service == null) {
- return Collections.emptyList();
- }
-
- return service.getDevicesMatchingConnectionStates(states);
- }
-
- @Override
- public int getConnectionState(BluetoothDevice device, AttributionSource source) {
- HearingAidService service = getService(source);
- if (service == null) {
- return STATE_DISCONNECTED;
- }
-
- return service.getConnectionState(device);
- }
-
- @Override
- public boolean setActiveDevice(BluetoothDevice device, AttributionSource source) {
- HearingAidService service = getService(source);
- if (service == null) {
- return false;
- }
-
- if (device == null) {
- return service.removeActiveDevice(false);
- } else {
- return service.setActiveDevice(device);
- }
- }
-
- @Override
- public List<BluetoothDevice> getActiveDevices(AttributionSource source) {
- HearingAidService service = getService(source);
- if (service == null) {
- return Collections.emptyList();
- }
-
- return service.getActiveDevices();
- }
-
- @Override
- public boolean setConnectionPolicy(
- BluetoothDevice device, int connectionPolicy, AttributionSource source) {
- HearingAidService service = getService(source);
- if (service == null) {
- return false;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- return service.setConnectionPolicy(device, connectionPolicy);
- }
-
- @Override
- public int getConnectionPolicy(BluetoothDevice device, AttributionSource source) {
- HearingAidService service = getService(source);
- if (service == null) {
- return CONNECTION_POLICY_UNKNOWN;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- return service.getConnectionPolicy(device);
- }
-
- @Override
- public void setVolume(int volume, AttributionSource source) {
- HearingAidService service = getService(source);
- if (service == null) {
- return;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- service.setVolume(volume);
- }
-
- @Override
- public long getHiSyncId(BluetoothDevice device, AttributionSource source) {
- HearingAidService service = getService(source);
- if (service == null) {
- return BluetoothHearingAid.HI_SYNC_ID_INVALID;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- return service.getHiSyncId(device);
- }
-
- @Override
- public int getDeviceSide(BluetoothDevice device, AttributionSource source) {
- HearingAidService service = getService(source);
- if (service == null) {
- return BluetoothHearingAid.SIDE_UNKNOWN;
- }
-
- int side = service.getCapabilities(device);
- if (side != BluetoothHearingAid.SIDE_UNKNOWN) {
- side &= 1;
- }
-
- return side;
- }
-
- @Override
- public int getDeviceMode(BluetoothDevice device, AttributionSource source) {
- HearingAidService service = getService(source);
- if (service == null) {
- return BluetoothHearingAid.MODE_UNKNOWN;
- }
-
- int mode = service.getCapabilities(device);
- if (mode != BluetoothHearingAid.MODE_UNKNOWN) {
- mode = mode >> 1 & 1;
- }
-
- return mode;
- }
-
- @Override
- public AdvertisementServiceData getAdvertisementServiceData(
- BluetoothDevice device, AttributionSource source) {
- HearingAidService service = mService;
-
- if (!Utils.checkServiceAvailable(service, TAG)
- || !Utils.checkCallerIsSystemOrActiveOrManagedUser(service, TAG)
- || !Utils.checkScanPermissionForDataDelivery(service, source, TAG)) {
- return null;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- return service.getAdvertisementServiceData(device);
- }
- }
-
@Override
public void dump(StringBuilder sb) {
super.dump(sb);
diff --git a/android/app/src/com/android/bluetooth/hearingaid/HearingAidServiceBinder.java b/android/app/src/com/android/bluetooth/hearingaid/HearingAidServiceBinder.java
new file mode 100644
index 0000000000..de384fba5c
--- /dev/null
+++ b/android/app/src/com/android/bluetooth/hearingaid/HearingAidServiceBinder.java
@@ -0,0 +1,230 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.bluetooth.hearingaid;
+
+import static android.Manifest.permission.BLUETOOTH_CONNECT;
+import static android.Manifest.permission.BLUETOOTH_PRIVILEGED;
+import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_UNKNOWN;
+import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTED;
+
+import android.annotation.RequiresPermission;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothHearingAid;
+import android.bluetooth.BluetoothHearingAid.AdvertisementServiceData;
+import android.bluetooth.IBluetoothHearingAid;
+import android.content.AttributionSource;
+
+import com.android.bluetooth.Utils;
+import com.android.bluetooth.btservice.ProfileService.IProfileServiceBinder;
+
+import java.util.Collections;
+import java.util.List;
+
+class HearingAidServiceBinder extends IBluetoothHearingAid.Stub implements IProfileServiceBinder {
+ private static final String TAG = HearingAidServiceBinder.class.getSimpleName();
+
+ private HearingAidService mService;
+
+ HearingAidServiceBinder(HearingAidService svc) {
+ mService = svc;
+ }
+
+ @Override
+ public void cleanup() {
+ mService = null;
+ }
+
+ @RequiresPermission(BLUETOOTH_CONNECT)
+ private HearingAidService getService(AttributionSource source) {
+ HearingAidService service = mService;
+
+ if (Utils.isInstrumentationTestMode()) {
+ return service;
+ }
+
+ if (!Utils.checkServiceAvailable(service, TAG)
+ || !Utils.checkCallerIsSystemOrActiveOrManagedUser(service, TAG)
+ || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
+ return null;
+ }
+ return service;
+ }
+
+ @Override
+ public boolean connect(BluetoothDevice device, AttributionSource source) {
+ HearingAidService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.connect(device);
+ }
+
+ @Override
+ public boolean disconnect(BluetoothDevice device, AttributionSource source) {
+ HearingAidService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.disconnect(device);
+ }
+
+ @Override
+ public List<BluetoothDevice> getConnectedDevices(AttributionSource source) {
+ HearingAidService service = getService(source);
+ if (service == null) {
+ return Collections.emptyList();
+ }
+ return service.getConnectedDevices();
+ }
+
+ @Override
+ public List<BluetoothDevice> getDevicesMatchingConnectionStates(
+ int[] states, AttributionSource source) {
+ HearingAidService service = getService(source);
+ if (service == null) {
+ return Collections.emptyList();
+ }
+ return service.getDevicesMatchingConnectionStates(states);
+ }
+
+ @Override
+ public int getConnectionState(BluetoothDevice device, AttributionSource source) {
+ HearingAidService service = getService(source);
+ if (service == null) {
+ return STATE_DISCONNECTED;
+ }
+ return service.getConnectionState(device);
+ }
+
+ @Override
+ public boolean setActiveDevice(BluetoothDevice device, AttributionSource source) {
+ HearingAidService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+
+ if (device == null) {
+ return service.removeActiveDevice(false);
+ } else {
+ return service.setActiveDevice(device);
+ }
+ }
+
+ @Override
+ public List<BluetoothDevice> getActiveDevices(AttributionSource source) {
+ HearingAidService service = getService(source);
+ if (service == null) {
+ return Collections.emptyList();
+ }
+ return service.getActiveDevices();
+ }
+
+ @Override
+ public boolean setConnectionPolicy(
+ BluetoothDevice device, int connectionPolicy, AttributionSource source) {
+ HearingAidService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.setConnectionPolicy(device, connectionPolicy);
+ }
+
+ @Override
+ public int getConnectionPolicy(BluetoothDevice device, AttributionSource source) {
+ HearingAidService service = getService(source);
+ if (service == null) {
+ return CONNECTION_POLICY_UNKNOWN;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.getConnectionPolicy(device);
+ }
+
+ @Override
+ public void setVolume(int volume, AttributionSource source) {
+ HearingAidService service = getService(source);
+ if (service == null) {
+ return;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ service.setVolume(volume);
+ }
+
+ @Override
+ public long getHiSyncId(BluetoothDevice device, AttributionSource source) {
+ HearingAidService service = getService(source);
+ if (service == null) {
+ return BluetoothHearingAid.HI_SYNC_ID_INVALID;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.getHiSyncId(device);
+ }
+
+ @Override
+ public int getDeviceSide(BluetoothDevice device, AttributionSource source) {
+ HearingAidService service = getService(source);
+ if (service == null) {
+ return BluetoothHearingAid.SIDE_UNKNOWN;
+ }
+
+ int side = service.getCapabilities(device);
+ if (side != BluetoothHearingAid.SIDE_UNKNOWN) {
+ side &= 1;
+ }
+
+ return side;
+ }
+
+ @Override
+ public int getDeviceMode(BluetoothDevice device, AttributionSource source) {
+ HearingAidService service = getService(source);
+ if (service == null) {
+ return BluetoothHearingAid.MODE_UNKNOWN;
+ }
+
+ int mode = service.getCapabilities(device);
+ if (mode != BluetoothHearingAid.MODE_UNKNOWN) {
+ mode = mode >> 1 & 1;
+ }
+
+ return mode;
+ }
+
+ @Override
+ public AdvertisementServiceData getAdvertisementServiceData(
+ BluetoothDevice device, AttributionSource source) {
+ HearingAidService service = mService;
+
+ if (!Utils.checkServiceAvailable(service, TAG)
+ || !Utils.checkCallerIsSystemOrActiveOrManagedUser(service, TAG)
+ || !Utils.checkScanPermissionForDataDelivery(
+ service, source, TAG, "getAdvertisementServiceData")) {
+ return null;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.getAdvertisementServiceData(device);
+ }
+}
diff --git a/android/app/src/com/android/bluetooth/hearingaid/HearingAidStackEvent.java b/android/app/src/com/android/bluetooth/hearingaid/HearingAidStackEvent.java
index 522dedc03e..98f822d898 100644
--- a/android/app/src/com/android/bluetooth/hearingaid/HearingAidStackEvent.java
+++ b/android/app/src/com/android/bluetooth/hearingaid/HearingAidStackEvent.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 The Android Open Source Project
+ * Copyright (C) 2018 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.
diff --git a/android/app/src/com/android/bluetooth/hearingaid/HearingAidStateMachine.java b/android/app/src/com/android/bluetooth/hearingaid/HearingAidStateMachine.java
index bab78a2c6a..0897cc4887 100644
--- a/android/app/src/com/android/bluetooth/hearingaid/HearingAidStateMachine.java
+++ b/android/app/src/com/android/bluetooth/hearingaid/HearingAidStateMachine.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 The Android Open Source Project
+ * Copyright (C) 2018 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.
diff --git a/android/app/src/com/android/bluetooth/hfp/HeadsetAgIndicatorEnableState.java b/android/app/src/com/android/bluetooth/hfp/HeadsetAgIndicatorEnableState.java
index 27c6343032..1df40d9f02 100644
--- a/android/app/src/com/android/bluetooth/hfp/HeadsetAgIndicatorEnableState.java
+++ b/android/app/src/com/android/bluetooth/hfp/HeadsetAgIndicatorEnableState.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 The Android Open Source Project
+ * Copyright (C) 2018 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.
diff --git a/android/app/src/com/android/bluetooth/hfp/HeadsetCallState.java b/android/app/src/com/android/bluetooth/hfp/HeadsetCallState.java
index a0d32c7e30..b88ce47e66 100644
--- a/android/app/src/com/android/bluetooth/hfp/HeadsetCallState.java
+++ b/android/app/src/com/android/bluetooth/hfp/HeadsetCallState.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 The Android Open Source Project
+ * Copyright (C) 2018 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.
diff --git a/android/app/src/com/android/bluetooth/hfp/HeadsetClccResponse.java b/android/app/src/com/android/bluetooth/hfp/HeadsetClccResponse.java
index bd47273e63..c3e92f6c0f 100644
--- a/android/app/src/com/android/bluetooth/hfp/HeadsetClccResponse.java
+++ b/android/app/src/com/android/bluetooth/hfp/HeadsetClccResponse.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 The Android Open Source Project
+ * Copyright (C) 2018 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.
diff --git a/android/app/src/com/android/bluetooth/hfp/HeadsetDeviceState.java b/android/app/src/com/android/bluetooth/hfp/HeadsetDeviceState.java
index 8f69c8cf60..395290c104 100644
--- a/android/app/src/com/android/bluetooth/hfp/HeadsetDeviceState.java
+++ b/android/app/src/com/android/bluetooth/hfp/HeadsetDeviceState.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 The Android Open Source Project
+ * Copyright (C) 2018 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.
diff --git a/android/app/src/com/android/bluetooth/hfp/HeadsetMessageObject.java b/android/app/src/com/android/bluetooth/hfp/HeadsetMessageObject.java
index 3d2701a57c..ec28f5dba9 100644
--- a/android/app/src/com/android/bluetooth/hfp/HeadsetMessageObject.java
+++ b/android/app/src/com/android/bluetooth/hfp/HeadsetMessageObject.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 The Android Open Source Project
+ * Copyright (C) 2018 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.
diff --git a/android/app/src/com/android/bluetooth/hfp/HeadsetNativeInterface.java b/android/app/src/com/android/bluetooth/hfp/HeadsetNativeInterface.java
index 9606d32cca..5afe78cee5 100644
--- a/android/app/src/com/android/bluetooth/hfp/HeadsetNativeInterface.java
+++ b/android/app/src/com/android/bluetooth/hfp/HeadsetNativeInterface.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017 The Android Open Source Project
+ * Copyright (C) 2017 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.
@@ -26,7 +26,6 @@ import com.android.bluetooth.Utils;
import com.android.bluetooth.btservice.AdapterService;
import com.android.bluetooth.flags.Flags;
import com.android.internal.annotations.GuardedBy;
-import com.android.internal.annotations.VisibleForTesting;
/**
* Defines native calls that are used by state machine/service to either send or receive messages
@@ -64,7 +63,6 @@ public class HeadsetNativeInterface {
}
/** Set singleton instance. */
- @VisibleForTesting
public static void setInstance(HeadsetNativeInterface instance) {
synchronized (INSTANCE_LOCK) {
sInstance = instance;
@@ -262,14 +260,12 @@ public class HeadsetNativeInterface {
* @param maxHfClients maximum number of headset clients that can be connected simultaneously
* @param inbandRingingEnabled whether in-band ringing is enabled on this AG
*/
- @VisibleForTesting
- public void init(int maxHfClients, boolean inbandRingingEnabled) {
+ void init(int maxHfClients, boolean inbandRingingEnabled) {
initializeNative(maxHfClients, inbandRingingEnabled);
}
/** Closes the interface */
- @VisibleForTesting
- public void cleanup() {
+ void cleanup() {
cleanupNative();
}
@@ -281,8 +277,7 @@ public class HeadsetNativeInterface {
* @param errorCode error code in case of ERROR
* @return True on success, False on failure
*/
- @VisibleForTesting
- public boolean atResponseCode(BluetoothDevice device, int responseCode, int errorCode) {
+ boolean atResponseCode(BluetoothDevice device, int responseCode, int errorCode) {
return atResponseCodeNative(responseCode, errorCode, getByteAddress(device));
}
@@ -293,8 +288,7 @@ public class HeadsetNativeInterface {
* @param responseString formatted AT response string
* @return True on success, False on failure
*/
- @VisibleForTesting
- public boolean atResponseString(BluetoothDevice device, String responseString) {
+ boolean atResponseString(BluetoothDevice device, String responseString) {
return atResponseStringNative(responseString, getByteAddress(device));
}
@@ -304,8 +298,7 @@ public class HeadsetNativeInterface {
* @param device target headset
* @return True on success, False on failure
*/
- @VisibleForTesting
- public boolean connectHfp(BluetoothDevice device) {
+ boolean connectHfp(BluetoothDevice device) {
return connectHfpNative(getByteAddress(device));
}
@@ -315,8 +308,7 @@ public class HeadsetNativeInterface {
* @param device target headset
* @return True on success, False on failure
*/
- @VisibleForTesting
- public boolean disconnectHfp(BluetoothDevice device) {
+ boolean disconnectHfp(BluetoothDevice device) {
return disconnectHfpNative(getByteAddress(device));
}
@@ -326,8 +318,7 @@ public class HeadsetNativeInterface {
* @param device target headset
* @return True on success, False on failure
*/
- @VisibleForTesting
- public boolean connectAudio(BluetoothDevice device) {
+ boolean connectAudio(BluetoothDevice device) {
return connectAudioNative(getByteAddress(device));
}
@@ -337,8 +328,7 @@ public class HeadsetNativeInterface {
* @param device target headset
* @return True on success, False on failure
*/
- @VisibleForTesting
- public boolean disconnectAudio(BluetoothDevice device) {
+ boolean disconnectAudio(BluetoothDevice device) {
return disconnectAudioNative(getByteAddress(device));
}
@@ -349,7 +339,7 @@ public class HeadsetNativeInterface {
* @param device target headset
* @return true if the device support echo cancellation or noise reduction, false otherwise
*/
- public boolean isNoiseReductionSupported(BluetoothDevice device) {
+ boolean isNoiseReductionSupported(BluetoothDevice device) {
return isNoiseReductionSupportedNative(getByteAddress(device));
}
@@ -359,7 +349,7 @@ public class HeadsetNativeInterface {
* @param device target headset
* @return true if the device supports voice recognition, false otherwise
*/
- public boolean isVoiceRecognitionSupported(BluetoothDevice device) {
+ boolean isVoiceRecognitionSupported(BluetoothDevice device) {
return isVoiceRecognitionSupportedNative(getByteAddress(device));
}
@@ -367,11 +357,11 @@ public class HeadsetNativeInterface {
* Start voice recognition
*
* @param device target headset
+ * @param sendResult whether a BVRA response should be sent
* @return True on success, False on failure
*/
- @VisibleForTesting
- public boolean startVoiceRecognition(BluetoothDevice device) {
- return startVoiceRecognitionNative(getByteAddress(device));
+ boolean startVoiceRecognition(BluetoothDevice device, boolean sendResult) {
+ return startVoiceRecognitionNative(getByteAddress(device), sendResult);
}
/**
@@ -380,8 +370,7 @@ public class HeadsetNativeInterface {
* @param device target headset
* @return True on success, False on failure
*/
- @VisibleForTesting
- public boolean stopVoiceRecognition(BluetoothDevice device) {
+ boolean stopVoiceRecognition(BluetoothDevice device) {
return stopVoiceRecognitionNative(getByteAddress(device));
}
@@ -393,8 +382,7 @@ public class HeadsetNativeInterface {
* @param volume value value
* @return True on success, False on failure
*/
- @VisibleForTesting
- public boolean setVolume(BluetoothDevice device, int volumeType, int volume) {
+ boolean setVolume(BluetoothDevice device, int volumeType, int volume) {
return setVolumeNative(volumeType, volume, getByteAddress(device));
}
@@ -411,8 +399,7 @@ public class HeadsetNativeInterface {
* @param batteryCharge battery charge level [0-5]
* @return True on success, False on failure
*/
- @VisibleForTesting
- public boolean cindResponse(
+ boolean cindResponse(
BluetoothDevice device,
int service,
int numActive,
@@ -439,8 +426,7 @@ public class HeadsetNativeInterface {
* @param deviceState device status object
* @return True on success, False on failure
*/
- @VisibleForTesting
- public boolean notifyDeviceStatus(BluetoothDevice device, HeadsetDeviceState deviceState) {
+ boolean notifyDeviceStatus(BluetoothDevice device, HeadsetDeviceState deviceState) {
return notifyDeviceStatusNative(
deviceState.mService,
deviceState.mRoam,
@@ -468,8 +454,7 @@ public class HeadsetNativeInterface {
* @param type optional
* @return True on success, False on failure
*/
- @VisibleForTesting
- public boolean clccResponse(
+ boolean clccResponse(
BluetoothDevice device,
int index,
int dir,
@@ -489,8 +474,7 @@ public class HeadsetNativeInterface {
* @param operatorName operator name
* @return True on success, False on failure
*/
- @VisibleForTesting
- public boolean copsResponse(BluetoothDevice device, String operatorName) {
+ boolean copsResponse(BluetoothDevice device, String operatorName) {
return copsResponseNative(operatorName, getByteAddress(device));
}
@@ -503,8 +487,7 @@ public class HeadsetNativeInterface {
* @param callState callState structure
* @return True on success, False on failure
*/
- @VisibleForTesting
- public boolean phoneStateChange(BluetoothDevice device, HeadsetCallState callState) {
+ boolean phoneStateChange(BluetoothDevice device, HeadsetCallState callState) {
return phoneStateChangeNative(
callState.mNumActive,
callState.mNumHeld,
@@ -521,8 +504,7 @@ public class HeadsetNativeInterface {
* @param value True to enable, False to disable
* @return True on success, False on failure
*/
- @VisibleForTesting
- public boolean setScoAllowed(boolean value) {
+ boolean setScoAllowed(boolean value) {
return setScoAllowedNative(value);
}
@@ -533,8 +515,7 @@ public class HeadsetNativeInterface {
* @param value True to enable, False to disable
* @return True on success, False on failure
*/
- @VisibleForTesting
- public boolean sendBsir(BluetoothDevice device, boolean value) {
+ boolean sendBsir(BluetoothDevice device, boolean value) {
return sendBsirNative(value, getByteAddress(device));
}
@@ -544,8 +525,7 @@ public class HeadsetNativeInterface {
* @param device current active SCO device
* @return true on success
*/
- @VisibleForTesting
- public boolean setActiveDevice(BluetoothDevice device) {
+ boolean setActiveDevice(BluetoothDevice device) {
return setActiveDeviceNative(getByteAddress(device));
}
@@ -582,7 +562,7 @@ public class HeadsetNativeInterface {
private native boolean isVoiceRecognitionSupportedNative(byte[] address);
- private native boolean startVoiceRecognitionNative(byte[] address);
+ private native boolean startVoiceRecognitionNative(byte[] address, boolean sendResult);
private native boolean stopVoiceRecognitionNative(byte[] address);
diff --git a/android/app/src/com/android/bluetooth/hfp/HeadsetObjectsFactory.java b/android/app/src/com/android/bluetooth/hfp/HeadsetObjectsFactory.java
index 3e2948c382..89e86e7842 100644
--- a/android/app/src/com/android/bluetooth/hfp/HeadsetObjectsFactory.java
+++ b/android/app/src/com/android/bluetooth/hfp/HeadsetObjectsFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 The Android Open Source Project
+ * Copyright (C) 2018 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.
diff --git a/android/app/src/com/android/bluetooth/hfp/HeadsetService.java b/android/app/src/com/android/bluetooth/hfp/HeadsetService.java
index 98f066d943..c5ab1f8dde 100644
--- a/android/app/src/com/android/bluetooth/hfp/HeadsetService.java
+++ b/android/app/src/com/android/bluetooth/hfp/HeadsetService.java
@@ -17,8 +17,6 @@
package com.android.bluetooth.hfp;
import static android.Manifest.permission.BLUETOOTH_CONNECT;
-import static android.Manifest.permission.BLUETOOTH_PRIVILEGED;
-import static android.Manifest.permission.MODIFY_PHONE_STATE;
import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_ALLOWED;
import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_UNKNOWN;
@@ -33,15 +31,12 @@ import static java.util.Objects.requireNonNull;
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.annotation.RequiresPermission;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHeadset;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothSinkAudioPolicy;
import android.bluetooth.BluetoothStatusCodes;
import android.bluetooth.BluetoothUuid;
-import android.bluetooth.IBluetoothHeadset;
-import android.content.AttributionSource;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -62,7 +57,6 @@ import android.sysprop.BluetoothProperties;
import android.telecom.PhoneAccount;
import android.util.Log;
-import com.android.bluetooth.BluetoothMetricsProto;
import com.android.bluetooth.BluetoothStatsLog;
import com.android.bluetooth.Utils;
import com.android.bluetooth.a2dp.A2dpService;
@@ -81,7 +75,6 @@ import com.android.internal.annotations.VisibleForTesting;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
@@ -238,7 +231,7 @@ public class HeadsetService extends ProfileService {
@Override
public IProfileServiceBinder initBinder() {
- return new BluetoothHeadsetBinder(this);
+ return new HeadsetServiceBinder(this);
}
@Override
@@ -517,303 +510,6 @@ public class HeadsetService extends ProfileService {
}
}
- /** Handlers for incoming service calls */
- @VisibleForTesting
- static class BluetoothHeadsetBinder extends IBluetoothHeadset.Stub
- implements IProfileServiceBinder {
- private HeadsetService mService;
-
- BluetoothHeadsetBinder(HeadsetService svc) {
- mService = svc;
- }
-
- @Override
- public void cleanup() {
- mService = null;
- }
-
- @RequiresPermission(BLUETOOTH_CONNECT)
- private HeadsetService getService(AttributionSource source) {
- // Cache mService because it can change while getService is called
- HeadsetService service = mService;
-
- if (Utils.isInstrumentationTestMode()) {
- return service;
- }
-
- if (!Utils.checkServiceAvailable(service, TAG)
- || !Utils.checkCallerIsSystemOrActiveOrManagedUser(service, TAG)
- || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
- return null;
- }
- return service;
- }
-
- @Override
- public boolean connect(BluetoothDevice device, AttributionSource source) {
- HeadsetService service = getService(source);
- if (service == null) {
- return false;
- }
-
- service.enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, null);
- return service.connect(device);
- }
-
- @Override
- public boolean disconnect(BluetoothDevice device, AttributionSource source) {
- HeadsetService service = getService(source);
- if (service == null) {
- return false;
- }
-
- return service.disconnect(device);
- }
-
- @Override
- public List<BluetoothDevice> getConnectedDevices(AttributionSource source) {
- HeadsetService service = getService(source);
- if (service == null) {
- return Collections.emptyList();
- }
-
- return service.getConnectedDevices();
- }
-
- @Override
- public List<BluetoothDevice> getDevicesMatchingConnectionStates(
- int[] states, AttributionSource source) {
- HeadsetService service = getService(source);
- if (service == null) {
- return Collections.emptyList();
- }
-
- return service.getDevicesMatchingConnectionStates(states);
- }
-
- @Override
- public int getConnectionState(BluetoothDevice device, AttributionSource source) {
- HeadsetService service = getService(source);
- if (service == null) {
- return STATE_DISCONNECTED;
- }
-
- return service.getConnectionState(device);
- }
-
- @Override
- public boolean setConnectionPolicy(
- BluetoothDevice device, int connectionPolicy, AttributionSource source) {
- HeadsetService service = getService(source);
- if (service == null) {
- return false;
- }
-
- service.enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, null);
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- return service.setConnectionPolicy(device, connectionPolicy);
- }
-
- @Override
- public int getConnectionPolicy(BluetoothDevice device, AttributionSource source) {
- HeadsetService service = getService(source);
- if (service == null) {
- return CONNECTION_POLICY_UNKNOWN;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- return service.getConnectionPolicy(device);
- }
-
- @Override
- public boolean isNoiseReductionSupported(BluetoothDevice device, AttributionSource source) {
- HeadsetService service = getService(source);
- if (service == null) {
- return false;
- }
-
- return service.isNoiseReductionSupported(device);
- }
-
- @Override
- public boolean isVoiceRecognitionSupported(
- BluetoothDevice device, AttributionSource source) {
- HeadsetService service = getService(source);
- if (service == null) {
- return false;
- }
-
- return service.isVoiceRecognitionSupported(device);
- }
-
- @Override
- public boolean startVoiceRecognition(BluetoothDevice device, AttributionSource source) {
- HeadsetService service = getService(source);
- if (service == null) {
- return false;
- }
-
- requireNonNull(device);
-
- return service.startVoiceRecognition(device);
- }
-
- @Override
- public boolean stopVoiceRecognition(BluetoothDevice device, AttributionSource source) {
- HeadsetService service = getService(source);
- if (service == null) {
- return false;
- }
-
- return service.stopVoiceRecognition(device);
- }
-
- @Override
- public boolean isAudioConnected(BluetoothDevice device, AttributionSource source) {
- HeadsetService service = getService(source);
- if (service == null) {
- return false;
- }
-
- return service.isAudioConnected(device);
- }
-
- @Override
- public int getAudioState(BluetoothDevice device, AttributionSource source) {
- HeadsetService service = getService(source);
- if (service == null) {
- return BluetoothHeadset.STATE_AUDIO_DISCONNECTED;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- return service.getAudioState(device);
- }
-
- @Override
- public int connectAudio(AttributionSource source) {
- HeadsetService service = getService(source);
- if (service == null) {
- return BluetoothStatusCodes.ERROR_PROFILE_SERVICE_NOT_BOUND;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- return service.connectAudio();
- }
-
- @Override
- public int disconnectAudio(AttributionSource source) {
- HeadsetService service = getService(source);
- if (service == null) {
- return BluetoothStatusCodes.ERROR_PROFILE_SERVICE_NOT_BOUND;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- return service.disconnectAudio();
- }
-
- @Override
- public void setAudioRouteAllowed(boolean allowed, AttributionSource source) {
- HeadsetService service = getService(source);
- if (service == null) {
- return;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- service.setAudioRouteAllowed(allowed);
- }
-
- @Override
- public boolean getAudioRouteAllowed(AttributionSource source) {
- HeadsetService service = getService(source);
- if (service == null) {
- return false;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- return service.getAudioRouteAllowed();
- }
-
- @Override
- public void setForceScoAudio(boolean forced, AttributionSource source) {
- HeadsetService service = getService(source);
- if (service == null) {
- return;
- }
-
- service.setForceScoAudio(forced);
- }
-
- @Override
- public boolean startScoUsingVirtualVoiceCall(AttributionSource source) {
- HeadsetService service = getService(source);
- if (service == null) {
- return false;
- }
-
- service.enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, null);
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- return service.startScoUsingVirtualVoiceCall();
- }
-
- @Override
- public boolean stopScoUsingVirtualVoiceCall(AttributionSource source) {
- HeadsetService service = getService(source);
- if (service == null) {
- return false;
- }
-
- service.enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, null);
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- return service.stopScoUsingVirtualVoiceCall();
- }
-
- @Override
- public boolean sendVendorSpecificResultCode(
- BluetoothDevice device, String command, String arg, AttributionSource source) {
- HeadsetService service = getService(source);
- if (service == null) {
- return false;
- }
-
- return service.sendVendorSpecificResultCode(device, command, arg);
- }
-
- @Override
- public boolean setActiveDevice(BluetoothDevice device, AttributionSource source) {
- HeadsetService service = getService(source);
- if (service == null) {
- return false;
- }
-
- service.enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, null);
-
- return service.setActiveDevice(device);
- }
-
- @Override
- public BluetoothDevice getActiveDevice(AttributionSource source) {
- HeadsetService service = getService(source);
- if (service == null) {
- return null;
- }
-
- return service.getActiveDevice();
- }
-
- @Override
- public boolean isInbandRingingEnabled(AttributionSource source) {
- HeadsetService service = getService(source);
- if (service == null) {
- return false;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- return service.isInbandRingingEnabled();
- }
- }
-
// API methods
public static synchronized HeadsetService getHeadsetService() {
if (sHeadsetService == null) {
@@ -948,7 +644,6 @@ public class HeadsetService extends ProfileService {
* @param states an array of states from {@link BluetoothProfile}
* @return a list of devices matching the array of connection states
*/
- @VisibleForTesting
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
ArrayList<BluetoothDevice> devices = new ArrayList<>();
synchronized (mStateMachines) {
@@ -1660,7 +1355,6 @@ public class HeadsetService extends ProfileService {
}
}
- @VisibleForTesting
boolean startScoUsingVirtualVoiceCall() {
Log.i(TAG, "startScoUsingVirtualVoiceCall: " + Utils.getUidPidString());
synchronized (mStateMachines) {
@@ -2135,8 +1829,7 @@ public class HeadsetService extends ProfileService {
}
}
- private boolean sendVendorSpecificResultCode(
- BluetoothDevice device, String command, String arg) {
+ boolean sendVendorSpecificResultCode(BluetoothDevice device, String command, String arg) {
synchronized (mStateMachines) {
final HeadsetStateMachine stateMachine = mStateMachines.get(device);
if (stateMachine == null) {
@@ -2215,7 +1908,6 @@ public class HeadsetService extends ProfileService {
BluetoothDevice device, int fromState, int toState) {
if (fromState != STATE_CONNECTED && toState == STATE_CONNECTED) {
updateInbandRinging(device, true);
- MetricsLogger.logProfileConnectionEvent(BluetoothMetricsProto.ProfileId.HEADSET);
}
if (fromState != STATE_DISCONNECTED && toState == STATE_DISCONNECTED) {
updateInbandRinging(device, false);
@@ -2398,9 +2090,10 @@ public class HeadsetService extends ProfileService {
// Do it here because some controllers cannot handle SCO and CIS
// co-existence see {@link LeAudioService#setInactiveForHfpHandover}
LeAudioService leAudioService = mFactory.getLeAudioService();
- boolean isLeAudioConnectedDeviceNotActive = leAudioService != null
- && !leAudioService.getConnectedDevices().isEmpty()
- && leAudioService.getActiveDevices().get(0) == null;
+ boolean isLeAudioConnectedDeviceNotActive =
+ leAudioService != null
+ && !leAudioService.getConnectedDevices().isEmpty()
+ && leAudioService.getActiveDevices().get(0) == null;
// usually controller limitation cause CONNECTING -> DISCONNECTED, so only
// resume LE audio active device if it is HFP audio only and SCO disconnected
if (fromState != BluetoothHeadset.STATE_AUDIO_CONNECTING
diff --git a/android/app/src/com/android/bluetooth/hfp/HeadsetServiceBinder.java b/android/app/src/com/android/bluetooth/hfp/HeadsetServiceBinder.java
new file mode 100644
index 0000000000..d93ad5dc5f
--- /dev/null
+++ b/android/app/src/com/android/bluetooth/hfp/HeadsetServiceBinder.java
@@ -0,0 +1,319 @@
+/*
+ * Copyright (C) 2022 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.hfp;
+
+import static android.Manifest.permission.BLUETOOTH_CONNECT;
+import static android.Manifest.permission.BLUETOOTH_PRIVILEGED;
+import static android.Manifest.permission.MODIFY_PHONE_STATE;
+import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_UNKNOWN;
+import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTED;
+
+import static java.util.Objects.requireNonNull;
+
+import android.annotation.RequiresPermission;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothHeadset;
+import android.bluetooth.BluetoothStatusCodes;
+import android.bluetooth.IBluetoothHeadset;
+import android.content.AttributionSource;
+
+import com.android.bluetooth.Utils;
+import com.android.bluetooth.btservice.ProfileService.IProfileServiceBinder;
+
+import java.util.Collections;
+import java.util.List;
+
+class HeadsetServiceBinder extends IBluetoothHeadset.Stub implements IProfileServiceBinder {
+ private static final String TAG = HeadsetServiceBinder.class.getSimpleName();
+
+ private HeadsetService mService;
+
+ HeadsetServiceBinder(HeadsetService svc) {
+ mService = svc;
+ }
+
+ @Override
+ public void cleanup() {
+ mService = null;
+ }
+
+ @RequiresPermission(BLUETOOTH_CONNECT)
+ private HeadsetService getService(AttributionSource source) {
+ HeadsetService service = mService;
+
+ if (Utils.isInstrumentationTestMode()) {
+ return service;
+ }
+
+ if (!Utils.checkServiceAvailable(service, TAG)
+ || !Utils.checkCallerIsSystemOrActiveOrManagedUser(service, TAG)
+ || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
+ return null;
+ }
+ return service;
+ }
+
+ @Override
+ public boolean connect(BluetoothDevice device, AttributionSource source) {
+ HeadsetService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+
+ service.enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, null);
+ return service.connect(device);
+ }
+
+ @Override
+ public boolean disconnect(BluetoothDevice device, AttributionSource source) {
+ HeadsetService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+ return service.disconnect(device);
+ }
+
+ @Override
+ public List<BluetoothDevice> getConnectedDevices(AttributionSource source) {
+ HeadsetService service = getService(source);
+ if (service == null) {
+ return Collections.emptyList();
+ }
+ return service.getConnectedDevices();
+ }
+
+ @Override
+ public List<BluetoothDevice> getDevicesMatchingConnectionStates(
+ int[] states, AttributionSource source) {
+ HeadsetService service = getService(source);
+ if (service == null) {
+ return Collections.emptyList();
+ }
+ return service.getDevicesMatchingConnectionStates(states);
+ }
+
+ @Override
+ public int getConnectionState(BluetoothDevice device, AttributionSource source) {
+ HeadsetService service = getService(source);
+ if (service == null) {
+ return STATE_DISCONNECTED;
+ }
+ return service.getConnectionState(device);
+ }
+
+ @Override
+ public boolean setConnectionPolicy(
+ BluetoothDevice device, int connectionPolicy, AttributionSource source) {
+ HeadsetService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+
+ service.enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, null);
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.setConnectionPolicy(device, connectionPolicy);
+ }
+
+ @Override
+ public int getConnectionPolicy(BluetoothDevice device, AttributionSource source) {
+ HeadsetService service = getService(source);
+ if (service == null) {
+ return CONNECTION_POLICY_UNKNOWN;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.getConnectionPolicy(device);
+ }
+
+ @Override
+ public boolean isNoiseReductionSupported(BluetoothDevice device, AttributionSource source) {
+ HeadsetService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+ return service.isNoiseReductionSupported(device);
+ }
+
+ @Override
+ public boolean isVoiceRecognitionSupported(BluetoothDevice device, AttributionSource source) {
+ HeadsetService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+ return service.isVoiceRecognitionSupported(device);
+ }
+
+ @Override
+ public boolean startVoiceRecognition(BluetoothDevice device, AttributionSource source) {
+ HeadsetService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+
+ requireNonNull(device);
+ return service.startVoiceRecognition(device);
+ }
+
+ @Override
+ public boolean stopVoiceRecognition(BluetoothDevice device, AttributionSource source) {
+ HeadsetService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+ return service.stopVoiceRecognition(device);
+ }
+
+ @Override
+ public boolean isAudioConnected(BluetoothDevice device, AttributionSource source) {
+ HeadsetService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+ return service.isAudioConnected(device);
+ }
+
+ @Override
+ public int getAudioState(BluetoothDevice device, AttributionSource source) {
+ HeadsetService service = getService(source);
+ if (service == null) {
+ return BluetoothHeadset.STATE_AUDIO_DISCONNECTED;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.getAudioState(device);
+ }
+
+ @Override
+ public int connectAudio(AttributionSource source) {
+ HeadsetService service = getService(source);
+ if (service == null) {
+ return BluetoothStatusCodes.ERROR_PROFILE_SERVICE_NOT_BOUND;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.connectAudio();
+ }
+
+ @Override
+ public int disconnectAudio(AttributionSource source) {
+ HeadsetService service = getService(source);
+ if (service == null) {
+ return BluetoothStatusCodes.ERROR_PROFILE_SERVICE_NOT_BOUND;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.disconnectAudio();
+ }
+
+ @Override
+ public void setAudioRouteAllowed(boolean allowed, AttributionSource source) {
+ HeadsetService service = getService(source);
+ if (service == null) {
+ return;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ service.setAudioRouteAllowed(allowed);
+ }
+
+ @Override
+ public boolean getAudioRouteAllowed(AttributionSource source) {
+ HeadsetService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.getAudioRouteAllowed();
+ }
+
+ @Override
+ public void setForceScoAudio(boolean forced, AttributionSource source) {
+ HeadsetService service = getService(source);
+ if (service == null) {
+ return;
+ }
+ service.setForceScoAudio(forced);
+ }
+
+ @Override
+ public boolean startScoUsingVirtualVoiceCall(AttributionSource source) {
+ HeadsetService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+
+ service.enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, null);
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+
+ return service.startScoUsingVirtualVoiceCall();
+ }
+
+ @Override
+ public boolean stopScoUsingVirtualVoiceCall(AttributionSource source) {
+ HeadsetService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+
+ service.enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, null);
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+
+ return service.stopScoUsingVirtualVoiceCall();
+ }
+
+ @Override
+ public boolean sendVendorSpecificResultCode(
+ BluetoothDevice device, String command, String arg, AttributionSource source) {
+ HeadsetService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+ return service.sendVendorSpecificResultCode(device, command, arg);
+ }
+
+ @Override
+ public boolean setActiveDevice(BluetoothDevice device, AttributionSource source) {
+ HeadsetService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+
+ service.enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, null);
+ return service.setActiveDevice(device);
+ }
+
+ @Override
+ public BluetoothDevice getActiveDevice(AttributionSource source) {
+ HeadsetService service = getService(source);
+ if (service == null) {
+ return null;
+ }
+ return service.getActiveDevice();
+ }
+
+ @Override
+ public boolean isInbandRingingEnabled(AttributionSource source) {
+ HeadsetService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.isInbandRingingEnabled();
+ }
+}
diff --git a/android/app/src/com/android/bluetooth/hfp/HeadsetStackEvent.java b/android/app/src/com/android/bluetooth/hfp/HeadsetStackEvent.java
index 6e669e576a..e477aa14ef 100644
--- a/android/app/src/com/android/bluetooth/hfp/HeadsetStackEvent.java
+++ b/android/app/src/com/android/bluetooth/hfp/HeadsetStackEvent.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017 The Android Open Source Project
+ * Copyright (C) 2017 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.
diff --git a/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java b/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java
index 4e8e14a547..6ea741af32 100644
--- a/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java
+++ b/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java
@@ -1044,7 +1044,8 @@ class HeadsetStateMachine extends StateMachine {
+ " is not currentDevice");
break;
}
- if (!mNativeInterface.startVoiceRecognition(mDevice)) {
+ if (!mNativeInterface.startVoiceRecognition(
+ mDevice, /* sendResult */ true)) {
stateLogW("Failed to start voice recognition");
break;
}
@@ -1122,6 +1123,9 @@ class HeadsetStateMachine extends StateMachine {
? HeadsetHalConstants.AT_RESPONSE_OK
: HeadsetHalConstants.AT_RESPONSE_ERROR,
0);
+ if (Utils.isScoManagedByAudioEnabled()) {
+ mNativeInterface.startVoiceRecognition(mDevice, /* sendResult */ false);
+ }
break;
}
case DIALING_OUT_RESULT:
diff --git a/android/app/src/com/android/bluetooth/hfp/HeadsetSystemInterface.java b/android/app/src/com/android/bluetooth/hfp/HeadsetSystemInterface.java
index 67967e941b..97525cc913 100644
--- a/android/app/src/com/android/bluetooth/hfp/HeadsetSystemInterface.java
+++ b/android/app/src/com/android/bluetooth/hfp/HeadsetSystemInterface.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017 The Android Open Source Project
+ * Copyright (C) 2017 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.
@@ -16,7 +16,6 @@
package com.android.bluetooth.hfp;
-
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHeadset;
import android.bluetooth.BluetoothSinkAudioPolicy;
diff --git a/android/app/src/com/android/bluetooth/hfp/HeadsetVendorSpecificResultCode.java b/android/app/src/com/android/bluetooth/hfp/HeadsetVendorSpecificResultCode.java
index 4acc211087..1c56188fd5 100644
--- a/android/app/src/com/android/bluetooth/hfp/HeadsetVendorSpecificResultCode.java
+++ b/android/app/src/com/android/bluetooth/hfp/HeadsetVendorSpecificResultCode.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 The Android Open Source Project
+ * Copyright (C) 2018 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.
diff --git a/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientService.java b/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientService.java
index 9c0e416168..7d3a5ff43f 100644
--- a/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientService.java
+++ b/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientService.java
@@ -16,11 +16,8 @@
package com.android.bluetooth.hfpclient;
-import static android.Manifest.permission.BLUETOOTH_CONNECT;
-import static android.Manifest.permission.BLUETOOTH_PRIVILEGED;
import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_ALLOWED;
import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
-import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_UNKNOWN;
import static android.bluetooth.BluetoothProfile.STATE_CONNECTED;
import static android.bluetooth.BluetoothProfile.STATE_CONNECTING;
import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTED;
@@ -28,15 +25,11 @@ import static android.content.pm.PackageManager.FEATURE_WATCH;
import static java.util.Objects.requireNonNull;
-import android.annotation.RequiresPermission;
import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothHeadsetClient;
import android.bluetooth.BluetoothHeadsetClientCall;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothSinkAudioPolicy;
import android.bluetooth.BluetoothStatusCodes;
-import android.bluetooth.IBluetoothHeadsetClient;
-import android.content.AttributionSource;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -58,7 +51,6 @@ import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -145,7 +137,7 @@ public class HeadsetClientService extends ProfileService {
@Override
public IProfileServiceBinder initBinder() {
- return new BluetoothHeadsetClientBinder(this);
+ return new HeadsetClientServiceBinder(this);
}
@Override
@@ -290,340 +282,6 @@ public class HeadsetClientService extends ProfileService {
call.isInBandRing());
}
- /** Handlers for incoming service calls */
- @VisibleForTesting
- static class BluetoothHeadsetClientBinder extends IBluetoothHeadsetClient.Stub
- implements IProfileServiceBinder {
- private HeadsetClientService mService;
-
- BluetoothHeadsetClientBinder(HeadsetClientService svc) {
- mService = svc;
- }
-
- @Override
- public void cleanup() {
- mService = null;
- }
-
- @RequiresPermission(BLUETOOTH_CONNECT)
- private HeadsetClientService getService(AttributionSource source) {
- // Cache mService because it can change while getService is called
- HeadsetClientService service = mService;
-
- if (Utils.isInstrumentationTestMode()) {
- return service;
- }
-
- if (!Utils.checkServiceAvailable(service, TAG)
- || !Utils.checkCallerIsSystemOrActiveOrManagedUser(service, TAG)
- || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
- return null;
- }
-
- return service;
- }
-
- @Override
- public boolean connect(BluetoothDevice device, AttributionSource source) {
- HeadsetClientService service = getService(source);
- if (service == null) {
- return false;
- }
-
- return service.connect(device);
- }
-
- @Override
- public boolean disconnect(BluetoothDevice device, AttributionSource source) {
- HeadsetClientService service = getService(source);
- if (service == null) {
- return false;
- }
-
- return service.disconnect(device);
- }
-
- @Override
- public List<BluetoothDevice> getConnectedDevices(AttributionSource source) {
- HeadsetClientService service = getService(source);
- if (service == null) {
- return Collections.emptyList();
- }
-
- service.enforceCallingPermission(BLUETOOTH_PRIVILEGED, null);
-
- return service.getConnectedDevices();
- }
-
- @Override
- public List<BluetoothDevice> getDevicesMatchingConnectionStates(
- int[] states, AttributionSource source) {
- HeadsetClientService service = getService(source);
- if (service == null) {
- return Collections.emptyList();
- }
-
- service.enforceCallingPermission(BLUETOOTH_PRIVILEGED, null);
-
- return service.getDevicesMatchingConnectionStates(states);
- }
-
- @Override
- public int getConnectionState(BluetoothDevice device, AttributionSource source) {
- HeadsetClientService service = getService(source);
- if (service == null) {
- return STATE_DISCONNECTED;
- }
-
- service.enforceCallingPermission(BLUETOOTH_PRIVILEGED, null);
-
- return service.getConnectionState(device);
- }
-
- @Override
- public boolean setConnectionPolicy(
- BluetoothDevice device, int connectionPolicy, AttributionSource source) {
- HeadsetClientService service = getService(source);
- if (service == null) {
- return false;
- }
-
- service.enforceCallingPermission(BLUETOOTH_PRIVILEGED, null);
-
- return service.setConnectionPolicy(device, connectionPolicy);
- }
-
- @Override
- public int getConnectionPolicy(BluetoothDevice device, AttributionSource source) {
- HeadsetClientService service = getService(source);
- if (service == null) {
- return CONNECTION_POLICY_UNKNOWN;
- }
-
- service.enforceCallingPermission(BLUETOOTH_PRIVILEGED, null);
-
- return service.getConnectionPolicy(device);
- }
-
- @Override
- public boolean startVoiceRecognition(BluetoothDevice device, AttributionSource source) {
- HeadsetClientService service = getService(source);
- if (service == null) {
- return false;
- }
-
- return service.startVoiceRecognition(device);
- }
-
- @Override
- public boolean stopVoiceRecognition(BluetoothDevice device, AttributionSource source) {
- HeadsetClientService service = getService(source);
- if (service == null) {
- return false;
- }
-
- return service.stopVoiceRecognition(device);
- }
-
- @Override
- public int getAudioState(BluetoothDevice device, AttributionSource source) {
- HeadsetClientService service = getService(source);
- if (service == null) {
- return BluetoothHeadsetClient.STATE_AUDIO_DISCONNECTED;
- }
-
- return service.getAudioState(device);
- }
-
- @Override
- public void setAudioRouteAllowed(
- BluetoothDevice device, boolean allowed, AttributionSource source) {
- HeadsetClientService service = getService(source);
- if (service == null) {
- Log.w(TAG, "Service handle is null for setAudioRouteAllowed!");
- return;
- }
-
- service.setAudioRouteAllowed(device, allowed);
- }
-
- @Override
- public boolean getAudioRouteAllowed(BluetoothDevice device, AttributionSource source) {
- HeadsetClientService service = getService(source);
- if (service == null) {
- Log.w(TAG, "Service handle is null for getAudioRouteAllowed!");
- return false;
- }
-
- return service.getAudioRouteAllowed(device);
- }
-
- @Override
- public boolean connectAudio(BluetoothDevice device, AttributionSource source) {
- HeadsetClientService service = getService(source);
- if (service == null) {
- return false;
- }
-
- return service.connectAudio(device);
- }
-
- @Override
- public boolean disconnectAudio(BluetoothDevice device, AttributionSource source) {
- HeadsetClientService service = getService(source);
- if (service == null) {
- return false;
- }
-
- return service.disconnectAudio(device);
- }
-
- @Override
- public boolean acceptCall(BluetoothDevice device, int flag, AttributionSource source) {
- HeadsetClientService service = getService(source);
- if (service == null) {
- return false;
- }
-
- return service.acceptCall(device, flag);
- }
-
- @Override
- public boolean rejectCall(BluetoothDevice device, AttributionSource source) {
- HeadsetClientService service = getService(source);
- if (service == null) {
- return false;
- }
-
- return service.rejectCall(device);
- }
-
- @Override
- public boolean holdCall(BluetoothDevice device, AttributionSource source) {
- HeadsetClientService service = getService(source);
- if (service == null) {
- return false;
- }
-
- return service.holdCall(device);
- }
-
- @Override
- public boolean terminateCall(
- BluetoothDevice device, BluetoothHeadsetClientCall call, AttributionSource source) {
- HeadsetClientService service = getService(source);
- if (service == null) {
- Log.w(TAG, "service is null");
- return false;
- }
-
- return service.terminateCall(device, call != null ? call.getUUID() : null);
- }
-
- @Override
- public boolean explicitCallTransfer(BluetoothDevice device, AttributionSource source) {
- HeadsetClientService service = getService(source);
- if (service == null) {
- return false;
- }
-
- return service.explicitCallTransfer(device);
- }
-
- @Override
- public boolean enterPrivateMode(
- BluetoothDevice device, int index, AttributionSource source) {
- HeadsetClientService service = getService(source);
- if (service == null) {
- return false;
- }
-
- return service.enterPrivateMode(device, index);
- }
-
- @Override
- public BluetoothHeadsetClientCall dial(
- BluetoothDevice device, String number, AttributionSource source) {
- HeadsetClientService service = getService(source);
- if (service == null) {
- return null;
- }
-
- return toLegacyCall(service.dial(device, number));
- }
-
- @Override
- public List<BluetoothHeadsetClientCall> getCurrentCalls(
- BluetoothDevice device, AttributionSource source) {
- HeadsetClientService service = getService(source);
- List<BluetoothHeadsetClientCall> currentCalls = new ArrayList<>();
- if (service == null) {
- return currentCalls;
- }
-
- List<HfpClientCall> calls = service.getCurrentCalls(device);
- if (calls != null) {
- for (HfpClientCall call : calls) {
- currentCalls.add(toLegacyCall(call));
- }
- }
- return currentCalls;
- }
-
- @Override
- public boolean sendDTMF(BluetoothDevice device, byte code, AttributionSource source) {
- HeadsetClientService service = getService(source);
- if (service == null) {
- return false;
- }
-
- return service.sendDTMF(device, code);
- }
-
- @Override
- public boolean getLastVoiceTagNumber(BluetoothDevice device, AttributionSource source) {
- HeadsetClientService service = getService(source);
- if (service == null) {
- return false;
- }
-
- return service.getLastVoiceTagNumber(device);
- }
-
- @Override
- public Bundle getCurrentAgEvents(BluetoothDevice device, AttributionSource source) {
- HeadsetClientService service = getService(source);
- if (service == null) {
- return null;
- }
-
- service.enforceCallingPermission(BLUETOOTH_PRIVILEGED, null);
-
- return service.getCurrentAgEvents(device);
- }
-
- @Override
- public boolean sendVendorAtCommand(
- BluetoothDevice device, int vendorId, String atCommand, AttributionSource source) {
- HeadsetClientService service = getService(source);
- if (service == null) {
- return false;
- }
-
- return service.sendVendorAtCommand(device, vendorId, atCommand);
- }
-
- @Override
- public Bundle getCurrentAgFeatures(BluetoothDevice device, AttributionSource source) {
- HeadsetClientService service = getService(source);
- if (service == null) {
- return null;
- }
-
- return service.getCurrentAgFeaturesBundle(device);
- }
- }
-
// API methods
public static synchronized HeadsetClientService getHeadsetClientService() {
if (sHeadsetClientService == null) {
diff --git a/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientServiceBinder.java b/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientServiceBinder.java
new file mode 100644
index 0000000000..3232fccd4f
--- /dev/null
+++ b/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientServiceBinder.java
@@ -0,0 +1,345 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.bluetooth.hfpclient;
+
+import static android.Manifest.permission.BLUETOOTH_CONNECT;
+import static android.Manifest.permission.BLUETOOTH_PRIVILEGED;
+import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_UNKNOWN;
+import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTED;
+
+import android.annotation.RequiresPermission;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothHeadsetClient;
+import android.bluetooth.BluetoothHeadsetClientCall;
+import android.bluetooth.IBluetoothHeadsetClient;
+import android.content.AttributionSource;
+import android.os.Bundle;
+import android.util.Log;
+
+import com.android.bluetooth.Utils;
+import com.android.bluetooth.btservice.ProfileService.IProfileServiceBinder;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/** Handlers for incoming service calls */
+class HeadsetClientServiceBinder extends IBluetoothHeadsetClient.Stub
+ implements IProfileServiceBinder {
+ private static final String TAG = HeadsetClientServiceBinder.class.getSimpleName();
+
+ private HeadsetClientService mService;
+
+ HeadsetClientServiceBinder(HeadsetClientService svc) {
+ mService = svc;
+ }
+
+ @Override
+ public void cleanup() {
+ mService = null;
+ }
+
+ @RequiresPermission(BLUETOOTH_CONNECT)
+ private HeadsetClientService getService(AttributionSource source) {
+ HeadsetClientService service = mService;
+
+ if (Utils.isInstrumentationTestMode()) {
+ return service;
+ }
+
+ if (!Utils.checkServiceAvailable(service, TAG)
+ || !Utils.checkCallerIsSystemOrActiveOrManagedUser(service, TAG)
+ || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
+ return null;
+ }
+
+ return service;
+ }
+
+ @Override
+ public boolean connect(BluetoothDevice device, AttributionSource source) {
+ HeadsetClientService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+ return service.connect(device);
+ }
+
+ @Override
+ public boolean disconnect(BluetoothDevice device, AttributionSource source) {
+ HeadsetClientService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+ return service.disconnect(device);
+ }
+
+ @Override
+ public List<BluetoothDevice> getConnectedDevices(AttributionSource source) {
+ HeadsetClientService service = getService(source);
+ if (service == null) {
+ return Collections.emptyList();
+ }
+
+ service.enforceCallingPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.getConnectedDevices();
+ }
+
+ @Override
+ public List<BluetoothDevice> getDevicesMatchingConnectionStates(
+ int[] states, AttributionSource source) {
+ HeadsetClientService service = getService(source);
+ if (service == null) {
+ return Collections.emptyList();
+ }
+
+ service.enforceCallingPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.getDevicesMatchingConnectionStates(states);
+ }
+
+ @Override
+ public int getConnectionState(BluetoothDevice device, AttributionSource source) {
+ HeadsetClientService service = getService(source);
+ if (service == null) {
+ return STATE_DISCONNECTED;
+ }
+
+ service.enforceCallingPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.getConnectionState(device);
+ }
+
+ @Override
+ public boolean setConnectionPolicy(
+ BluetoothDevice device, int connectionPolicy, AttributionSource source) {
+ HeadsetClientService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+
+ service.enforceCallingPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.setConnectionPolicy(device, connectionPolicy);
+ }
+
+ @Override
+ public int getConnectionPolicy(BluetoothDevice device, AttributionSource source) {
+ HeadsetClientService service = getService(source);
+ if (service == null) {
+ return CONNECTION_POLICY_UNKNOWN;
+ }
+
+ service.enforceCallingPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.getConnectionPolicy(device);
+ }
+
+ @Override
+ public boolean startVoiceRecognition(BluetoothDevice device, AttributionSource source) {
+ HeadsetClientService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+ return service.startVoiceRecognition(device);
+ }
+
+ @Override
+ public boolean stopVoiceRecognition(BluetoothDevice device, AttributionSource source) {
+ HeadsetClientService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+ return service.stopVoiceRecognition(device);
+ }
+
+ @Override
+ public int getAudioState(BluetoothDevice device, AttributionSource source) {
+ HeadsetClientService service = getService(source);
+ if (service == null) {
+ return BluetoothHeadsetClient.STATE_AUDIO_DISCONNECTED;
+ }
+ return service.getAudioState(device);
+ }
+
+ @Override
+ public void setAudioRouteAllowed(
+ BluetoothDevice device, boolean allowed, AttributionSource source) {
+ HeadsetClientService service = getService(source);
+ if (service == null) {
+ Log.w(TAG, "Service handle is null for setAudioRouteAllowed!");
+ return;
+ }
+ service.setAudioRouteAllowed(device, allowed);
+ }
+
+ @Override
+ public boolean getAudioRouteAllowed(BluetoothDevice device, AttributionSource source) {
+ HeadsetClientService service = getService(source);
+ if (service == null) {
+ Log.w(TAG, "Service handle is null for getAudioRouteAllowed!");
+ return false;
+ }
+ return service.getAudioRouteAllowed(device);
+ }
+
+ @Override
+ public boolean connectAudio(BluetoothDevice device, AttributionSource source) {
+ HeadsetClientService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+ return service.connectAudio(device);
+ }
+
+ @Override
+ public boolean disconnectAudio(BluetoothDevice device, AttributionSource source) {
+ HeadsetClientService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+ return service.disconnectAudio(device);
+ }
+
+ @Override
+ public boolean acceptCall(BluetoothDevice device, int flag, AttributionSource source) {
+ HeadsetClientService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+ return service.acceptCall(device, flag);
+ }
+
+ @Override
+ public boolean rejectCall(BluetoothDevice device, AttributionSource source) {
+ HeadsetClientService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+ return service.rejectCall(device);
+ }
+
+ @Override
+ public boolean holdCall(BluetoothDevice device, AttributionSource source) {
+ HeadsetClientService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+ return service.holdCall(device);
+ }
+
+ @Override
+ public boolean terminateCall(
+ BluetoothDevice device, BluetoothHeadsetClientCall call, AttributionSource source) {
+ HeadsetClientService service = getService(source);
+ if (service == null) {
+ Log.w(TAG, "service is null");
+ return false;
+ }
+ return service.terminateCall(device, call != null ? call.getUUID() : null);
+ }
+
+ @Override
+ public boolean explicitCallTransfer(BluetoothDevice device, AttributionSource source) {
+ HeadsetClientService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+ return service.explicitCallTransfer(device);
+ }
+
+ @Override
+ public boolean enterPrivateMode(BluetoothDevice device, int index, AttributionSource source) {
+ HeadsetClientService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+ return service.enterPrivateMode(device, index);
+ }
+
+ @Override
+ public BluetoothHeadsetClientCall dial(
+ BluetoothDevice device, String number, AttributionSource source) {
+ HeadsetClientService service = getService(source);
+ if (service == null) {
+ return null;
+ }
+ return HeadsetClientService.toLegacyCall(service.dial(device, number));
+ }
+
+ @Override
+ public List<BluetoothHeadsetClientCall> getCurrentCalls(
+ BluetoothDevice device, AttributionSource source) {
+ HeadsetClientService service = getService(source);
+ List<BluetoothHeadsetClientCall> currentCalls = new ArrayList<>();
+ if (service == null) {
+ return currentCalls;
+ }
+
+ List<HfpClientCall> calls = service.getCurrentCalls(device);
+ if (calls != null) {
+ for (HfpClientCall call : calls) {
+ currentCalls.add(HeadsetClientService.toLegacyCall(call));
+ }
+ }
+ return currentCalls;
+ }
+
+ @Override
+ public boolean sendDTMF(BluetoothDevice device, byte code, AttributionSource source) {
+ HeadsetClientService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+ return service.sendDTMF(device, code);
+ }
+
+ @Override
+ public boolean getLastVoiceTagNumber(BluetoothDevice device, AttributionSource source) {
+ HeadsetClientService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+ return service.getLastVoiceTagNumber(device);
+ }
+
+ @Override
+ public Bundle getCurrentAgEvents(BluetoothDevice device, AttributionSource source) {
+ HeadsetClientService service = getService(source);
+ if (service == null) {
+ return null;
+ }
+
+ service.enforceCallingPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.getCurrentAgEvents(device);
+ }
+
+ @Override
+ public boolean sendVendorAtCommand(
+ BluetoothDevice device, int vendorId, String atCommand, AttributionSource source) {
+ HeadsetClientService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+ return service.sendVendorAtCommand(device, vendorId, atCommand);
+ }
+
+ @Override
+ public Bundle getCurrentAgFeatures(BluetoothDevice device, AttributionSource source) {
+ HeadsetClientService service = getService(source);
+ if (service == null) {
+ return null;
+ }
+ return service.getCurrentAgFeaturesBundle(device);
+ }
+}
diff --git a/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java b/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java
index 49153659fc..23ed0b7c7d 100644
--- a/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java
+++ b/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java
@@ -65,7 +65,6 @@ import android.os.SystemProperties;
import android.util.Log;
import android.util.Pair;
-import com.android.bluetooth.BluetoothMetricsProto;
import com.android.bluetooth.BluetoothStatsLog;
import com.android.bluetooth.R;
import com.android.bluetooth.Utils;
@@ -1386,8 +1385,6 @@ public class HeadsetClientStateMachine extends StateMachine {
if (mHeadsetService != null) {
mHeadsetService.updateInbandRinging(mCurrentDevice, true);
}
- MetricsLogger.logProfileConnectionEvent(
- BluetoothMetricsProto.ProfileId.HEADSET_CLIENT);
} else if (mPrevState != mAudioOn) {
String prevStateName = mPrevState == null ? "null" : mPrevState.getName();
error(
diff --git a/android/app/src/com/android/bluetooth/hfpclient/VendorCommandResponseProcessor.java b/android/app/src/com/android/bluetooth/hfpclient/VendorCommandResponseProcessor.java
index 603beae96b..ebd021c9ff 100644
--- a/android/app/src/com/android/bluetooth/hfpclient/VendorCommandResponseProcessor.java
+++ b/android/app/src/com/android/bluetooth/hfpclient/VendorCommandResponseProcessor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/android/app/src/com/android/bluetooth/hid/HidDeviceNativeInterface.java b/android/app/src/com/android/bluetooth/hid/HidDeviceNativeInterface.java
index 81da626bc8..2ca9078103 100644
--- a/android/app/src/com/android/bluetooth/hid/HidDeviceNativeInterface.java
+++ b/android/app/src/com/android/bluetooth/hid/HidDeviceNativeInterface.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017 The Android Open Source Project
+ * Copyright (C) 2017 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.
diff --git a/android/app/src/com/android/bluetooth/hid/HidDeviceService.java b/android/app/src/com/android/bluetooth/hid/HidDeviceService.java
index 6e5ea040ea..d3d84d9630 100644
--- a/android/app/src/com/android/bluetooth/hid/HidDeviceService.java
+++ b/android/app/src/com/android/bluetooth/hid/HidDeviceService.java
@@ -34,9 +34,7 @@ import android.bluetooth.BluetoothHidDevice;
import android.bluetooth.BluetoothHidDeviceAppQosSettings;
import android.bluetooth.BluetoothHidDeviceAppSdpSettings;
import android.bluetooth.BluetoothProfile;
-import android.bluetooth.IBluetoothHidDevice;
import android.bluetooth.IBluetoothHidDeviceCallback;
-import android.content.AttributionSource;
import android.content.Intent;
import android.os.Binder;
import android.os.Handler;
@@ -48,18 +46,14 @@ import android.os.RemoteException;
import android.sysprop.BluetoothProperties;
import android.util.Log;
-import com.android.bluetooth.BluetoothMetricsProto;
import com.android.bluetooth.Utils;
import com.android.bluetooth.btservice.AdapterService;
-import com.android.bluetooth.btservice.MetricsLogger;
import com.android.bluetooth.btservice.ProfileService;
import com.android.bluetooth.btservice.storage.DatabaseManager;
import com.android.internal.annotations.VisibleForTesting;
import java.nio.ByteBuffer;
import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
import java.util.List;
import java.util.NoSuchElementException;
@@ -329,204 +323,9 @@ public class HidDeviceService extends ProfileService {
}
};
- @VisibleForTesting
- static class BluetoothHidDeviceBinder extends IBluetoothHidDevice.Stub
- implements IProfileServiceBinder {
-
- private static final String TAG = BluetoothHidDeviceBinder.class.getSimpleName();
-
- private HidDeviceService mService;
-
- BluetoothHidDeviceBinder(HidDeviceService service) {
- mService = service;
- }
-
- @Override
- public void cleanup() {
- mService = null;
- }
-
- @RequiresPermission(BLUETOOTH_CONNECT)
- private HidDeviceService getService(AttributionSource source) {
- // Cache mService because it can change while getService is called
- HidDeviceService service = mService;
-
- if (Utils.isInstrumentationTestMode()) {
- return service;
- }
- if (!Utils.checkServiceAvailable(service, TAG)
- || !Utils.checkCallerIsSystemOrActiveOrManagedUser(service, TAG)
- || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
- return null;
- }
- return service;
- }
-
- @Override
- public boolean registerApp(
- BluetoothHidDeviceAppSdpSettings sdp,
- BluetoothHidDeviceAppQosSettings inQos,
- BluetoothHidDeviceAppQosSettings outQos,
- IBluetoothHidDeviceCallback callback,
- AttributionSource source) {
- Log.d(TAG, "registerApp()");
-
- HidDeviceService service = getService(source);
- if (service == null) {
- return false;
- }
-
- return service.registerApp(sdp, inQos, outQos, callback);
- }
-
- @Override
- public boolean unregisterApp(AttributionSource source) {
- Log.d(TAG, "unregisterApp()");
-
- HidDeviceService service = getService(source);
- if (service == null) {
- return false;
- }
-
- return service.unregisterApp();
- }
-
- @Override
- public boolean sendReport(
- BluetoothDevice device, int id, byte[] data, AttributionSource source) {
- Log.d(TAG, "sendReport(): device=" + device + " id=" + id);
-
- HidDeviceService service = getService(source);
- if (service == null) {
- return false;
- }
-
- return service.sendReport(device, id, data);
- }
-
- @Override
- public boolean replyReport(
- BluetoothDevice device, byte type, byte id, byte[] data, AttributionSource source) {
- Log.d(TAG, "replyReport(): device=" + device + " type=" + type + " id=" + id);
-
- HidDeviceService service = getService(source);
- if (service == null) {
- return false;
- }
-
- return service.replyReport(device, type, id, data);
- }
-
- @Override
- public boolean unplug(BluetoothDevice device, AttributionSource source) {
- Log.d(TAG, "unplug(): device=" + device);
-
- HidDeviceService service = getService(source);
- if (service == null) {
- return false;
- }
-
- return service.unplug(device);
- }
-
- @Override
- public boolean connect(BluetoothDevice device, AttributionSource source) {
- Log.d(TAG, "connect(): device=" + device);
-
- HidDeviceService service = getService(source);
- if (service == null) {
- return false;
- }
-
- return service.connect(device);
- }
-
- @Override
- public boolean disconnect(BluetoothDevice device, AttributionSource source) {
- Log.d(TAG, "disconnect(): device=" + device);
-
- HidDeviceService service = getService(source);
- if (service == null) {
- return false;
- }
-
- return service.disconnect(device);
- }
-
- @Override
- public boolean setConnectionPolicy(
- BluetoothDevice device, int connectionPolicy, AttributionSource source) {
- Log.d(
- TAG,
- "setConnectionPolicy():"
- + (" device=" + device)
- + (" connectionPolicy=" + connectionPolicy));
-
- HidDeviceService service = getService(source);
- if (service == null) {
- return false;
- }
-
- return service.setConnectionPolicy(device, connectionPolicy);
- }
-
- @Override
- public boolean reportError(BluetoothDevice device, byte error, AttributionSource source) {
- Log.d(TAG, "reportError(): device=" + device + " error=" + error);
-
- HidDeviceService service = getService(source);
- if (service == null) {
- return false;
- }
-
- return service.reportError(device, error);
- }
-
- @Override
- public int getConnectionState(BluetoothDevice device, AttributionSource source) {
- Log.d(TAG, "getConnectionState(): device=" + device);
-
- HidDeviceService service = getService(source);
- if (service == null) {
- return BluetoothHidDevice.STATE_DISCONNECTED;
- }
-
- return service.getConnectionState(device);
- }
-
- @Override
- public List<BluetoothDevice> getConnectedDevices(AttributionSource source) {
- Log.d(TAG, "getConnectedDevices()");
-
- return getDevicesMatchingConnectionStates(new int[] {STATE_CONNECTED}, source);
- }
-
- @Override
- public List<BluetoothDevice> getDevicesMatchingConnectionStates(
- int[] states, AttributionSource source) {
- Log.d(TAG, "getDevicesMatchingConnectionStates(): states=" + Arrays.toString(states));
-
- HidDeviceService service = getService(source);
- if (service == null) {
- return Collections.emptyList();
- }
-
- return service.getDevicesMatchingConnectionStates(states);
- }
-
- @Override
- public String getUserAppName(AttributionSource source) {
- HidDeviceService service = getService(source);
- if (service == null) {
- return "";
- }
- return service.getUserAppName();
- }
- }
-
@Override
protected IProfileServiceBinder initBinder() {
- return new BluetoothHidDeviceBinder(this);
+ return new HidDeviceServiceBinder(this);
}
private boolean checkDevice(BluetoothDevice device) {
@@ -888,10 +687,6 @@ public class HidDeviceService extends ProfileService {
mAdapterService.updateProfileConnectionAdapterProperties(
device, BluetoothProfile.HID_DEVICE, newState, prevState);
- if (newState == STATE_CONNECTED) {
- MetricsLogger.logProfileConnectionEvent(BluetoothMetricsProto.ProfileId.HID_DEVICE);
- }
-
Intent intent = new Intent(BluetoothHidDevice.ACTION_CONNECTION_STATE_CHANGED);
intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, prevState);
intent.putExtra(BluetoothProfile.EXTRA_STATE, newState);
diff --git a/android/app/src/com/android/bluetooth/hid/HidDeviceServiceBinder.java b/android/app/src/com/android/bluetooth/hid/HidDeviceServiceBinder.java
new file mode 100644
index 0000000000..0cd0e1d301
--- /dev/null
+++ b/android/app/src/com/android/bluetooth/hid/HidDeviceServiceBinder.java
@@ -0,0 +1,218 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.bluetooth.hid;
+
+import static android.Manifest.permission.BLUETOOTH_CONNECT;
+import static android.bluetooth.BluetoothProfile.STATE_CONNECTED;
+
+import android.annotation.RequiresPermission;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothHidDevice;
+import android.bluetooth.BluetoothHidDeviceAppQosSettings;
+import android.bluetooth.BluetoothHidDeviceAppSdpSettings;
+import android.bluetooth.IBluetoothHidDevice;
+import android.bluetooth.IBluetoothHidDeviceCallback;
+import android.content.AttributionSource;
+import android.util.Log;
+
+import com.android.bluetooth.Utils;
+import com.android.bluetooth.btservice.ProfileService.IProfileServiceBinder;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+class HidDeviceServiceBinder extends IBluetoothHidDevice.Stub implements IProfileServiceBinder {
+ private static final String TAG = HidDeviceServiceBinder.class.getSimpleName();
+
+ private HidDeviceService mService;
+
+ HidDeviceServiceBinder(HidDeviceService service) {
+ mService = service;
+ }
+
+ @Override
+ public void cleanup() {
+ mService = null;
+ }
+
+ @RequiresPermission(BLUETOOTH_CONNECT)
+ private HidDeviceService getService(AttributionSource source) {
+ // Cache mService because it can change while getService is called
+ HidDeviceService service = mService;
+
+ if (Utils.isInstrumentationTestMode()) {
+ return service;
+ }
+ if (!Utils.checkServiceAvailable(service, TAG)
+ || !Utils.checkCallerIsSystemOrActiveOrManagedUser(service, TAG)
+ || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
+ return null;
+ }
+ return service;
+ }
+
+ @Override
+ public boolean registerApp(
+ BluetoothHidDeviceAppSdpSettings sdp,
+ BluetoothHidDeviceAppQosSettings inQos,
+ BluetoothHidDeviceAppQosSettings outQos,
+ IBluetoothHidDeviceCallback callback,
+ AttributionSource source) {
+ Log.d(TAG, "registerApp()");
+
+ HidDeviceService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+ return service.registerApp(sdp, inQos, outQos, callback);
+ }
+
+ @Override
+ public boolean unregisterApp(AttributionSource source) {
+ Log.d(TAG, "unregisterApp()");
+
+ HidDeviceService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+ return service.unregisterApp();
+ }
+
+ @Override
+ public boolean sendReport(
+ BluetoothDevice device, int id, byte[] data, AttributionSource source) {
+ Log.d(TAG, "sendReport(): device=" + device + " id=" + id);
+
+ HidDeviceService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+ return service.sendReport(device, id, data);
+ }
+
+ @Override
+ public boolean replyReport(
+ BluetoothDevice device, byte type, byte id, byte[] data, AttributionSource source) {
+ Log.d(TAG, "replyReport(): device=" + device + " type=" + type + " id=" + id);
+
+ HidDeviceService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+ return service.replyReport(device, type, id, data);
+ }
+
+ @Override
+ public boolean unplug(BluetoothDevice device, AttributionSource source) {
+ Log.d(TAG, "unplug(): device=" + device);
+
+ HidDeviceService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+ return service.unplug(device);
+ }
+
+ @Override
+ public boolean connect(BluetoothDevice device, AttributionSource source) {
+ Log.d(TAG, "connect(): device=" + device);
+
+ HidDeviceService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+ return service.connect(device);
+ }
+
+ @Override
+ public boolean disconnect(BluetoothDevice device, AttributionSource source) {
+ Log.d(TAG, "disconnect(): device=" + device);
+
+ HidDeviceService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+ return service.disconnect(device);
+ }
+
+ @Override
+ public boolean setConnectionPolicy(
+ BluetoothDevice device, int connectionPolicy, AttributionSource source) {
+ Log.d(
+ TAG,
+ "setConnectionPolicy():"
+ + (" device=" + device)
+ + (" connectionPolicy=" + connectionPolicy));
+
+ HidDeviceService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+ return service.setConnectionPolicy(device, connectionPolicy);
+ }
+
+ @Override
+ public boolean reportError(BluetoothDevice device, byte error, AttributionSource source) {
+ Log.d(TAG, "reportError(): device=" + device + " error=" + error);
+
+ HidDeviceService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+ return service.reportError(device, error);
+ }
+
+ @Override
+ public int getConnectionState(BluetoothDevice device, AttributionSource source) {
+ Log.d(TAG, "getConnectionState(): device=" + device);
+
+ HidDeviceService service = getService(source);
+ if (service == null) {
+ return BluetoothHidDevice.STATE_DISCONNECTED;
+ }
+ return service.getConnectionState(device);
+ }
+
+ @Override
+ public List<BluetoothDevice> getConnectedDevices(AttributionSource source) {
+ Log.d(TAG, "getConnectedDevices()");
+
+ return getDevicesMatchingConnectionStates(new int[] {STATE_CONNECTED}, source);
+ }
+
+ @Override
+ public List<BluetoothDevice> getDevicesMatchingConnectionStates(
+ int[] states, AttributionSource source) {
+ Log.d(TAG, "getDevicesMatchingConnectionStates(): states=" + Arrays.toString(states));
+
+ HidDeviceService service = getService(source);
+ if (service == null) {
+ return Collections.emptyList();
+ }
+ return service.getDevicesMatchingConnectionStates(states);
+ }
+
+ @Override
+ public String getUserAppName(AttributionSource source) {
+ HidDeviceService service = getService(source);
+ if (service == null) {
+ return "";
+ }
+ return service.getUserAppName();
+ }
+}
diff --git a/android/app/src/com/android/bluetooth/hid/HidHostNativeInterface.java b/android/app/src/com/android/bluetooth/hid/HidHostNativeInterface.java
index 1d0294cd52..bac98af1cc 100644
--- a/android/app/src/com/android/bluetooth/hid/HidHostNativeInterface.java
+++ b/android/app/src/com/android/bluetooth/hid/HidHostNativeInterface.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 The Android Open Source Project
+ * Copyright (C) 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.
diff --git a/android/app/src/com/android/bluetooth/hid/HidHostService.java b/android/app/src/com/android/bluetooth/hid/HidHostService.java
index 1f1cd866ab..1eac6ed336 100644
--- a/android/app/src/com/android/bluetooth/hid/HidHostService.java
+++ b/android/app/src/com/android/bluetooth/hid/HidHostService.java
@@ -17,7 +17,6 @@
package com.android.bluetooth.hid;
import static android.Manifest.permission.BLUETOOTH_CONNECT;
-import static android.Manifest.permission.BLUETOOTH_PRIVILEGED;
import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_ALLOWED;
import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_UNKNOWN;
@@ -27,14 +26,11 @@ import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTING;
import static java.util.Objects.requireNonNull;
-import android.annotation.RequiresPermission;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHidHost;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothProtoEnums;
import android.bluetooth.BluetoothUuid;
-import android.bluetooth.IBluetoothHidHost;
-import android.content.AttributionSource;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
@@ -46,7 +42,6 @@ import android.util.Log;
import androidx.annotation.VisibleForTesting;
-import com.android.bluetooth.BluetoothMetricsProto;
import com.android.bluetooth.Utils;
import com.android.bluetooth.btservice.AdapterService;
import com.android.bluetooth.btservice.MetricsLogger;
@@ -146,7 +141,7 @@ public class HidHostService extends ProfileService {
@Override
public IProfileServiceBinder initBinder() {
- return new BluetoothHidHostBinder(this);
+ return new HidHostServiceBinder(this);
}
@Override
@@ -714,207 +709,6 @@ public class HidHostService extends ProfileService {
return true;
}
- @VisibleForTesting
- static class BluetoothHidHostBinder extends IBluetoothHidHost.Stub
- implements IProfileServiceBinder {
- private HidHostService mService;
-
- BluetoothHidHostBinder(HidHostService svc) {
- mService = svc;
- }
-
- @Override
- public void cleanup() {
- mService = null;
- }
-
- @RequiresPermission(BLUETOOTH_CONNECT)
- private HidHostService getService(AttributionSource source) {
- // Cache mService because it can change while getService is called
- HidHostService service = mService;
-
- if (Utils.isInstrumentationTestMode()) {
- return service;
- }
-
- if (!Utils.checkServiceAvailable(service, TAG)
- || !Utils.checkCallerIsSystemOrActiveOrManagedUser(service, TAG)
- || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
- return null;
- }
-
- return service;
- }
-
- @Override
- public boolean connect(BluetoothDevice device, AttributionSource source) {
- HidHostService service = getService(source);
- if (service == null) {
- return false;
- }
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- return service.connect(device);
- }
-
- @Override
- public boolean disconnect(BluetoothDevice device, AttributionSource source) {
- HidHostService service = getService(source);
- if (service == null) {
- return false;
- }
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- return service.disconnect(device);
- }
-
- @Override
- public int getConnectionState(BluetoothDevice device, AttributionSource source) {
- HidHostService service = getService(source);
- if (service == null) {
- return STATE_DISCONNECTED;
- }
- return service.getConnectionState(device);
- }
-
- @Override
- public List<BluetoothDevice> getConnectedDevices(AttributionSource source) {
- return getDevicesMatchingConnectionStates(new int[] {STATE_CONNECTED}, source);
- }
-
- @Override
- public List<BluetoothDevice> getDevicesMatchingConnectionStates(
- int[] states, AttributionSource source) {
- HidHostService service = getService(source);
- if (service == null) {
- return Collections.emptyList();
- }
- return service.getDevicesMatchingConnectionStates(states);
- }
-
- @Override
- public boolean setConnectionPolicy(
- BluetoothDevice device, int connectionPolicy, AttributionSource source) {
- HidHostService service = getService(source);
- if (service == null) {
- return false;
- }
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- return service.setConnectionPolicy(device, connectionPolicy);
- }
-
- @Override
- public int getConnectionPolicy(BluetoothDevice device, AttributionSource source) {
- HidHostService service = getService(source);
- if (service == null) {
- return CONNECTION_POLICY_UNKNOWN;
- }
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- return service.getConnectionPolicy(device);
- }
-
- @Override
- public boolean setPreferredTransport(
- BluetoothDevice device, int transport, AttributionSource source) {
- HidHostService service = getService(source);
- if (service == null) {
- return false;
- }
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- return service.setPreferredTransport(device, transport);
- }
-
- @Override
- public int getPreferredTransport(BluetoothDevice device, AttributionSource source) {
- HidHostService service = getService(source);
- if (service == null) {
- return BluetoothDevice.TRANSPORT_AUTO;
- }
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- return service.getPreferredTransport(device);
- }
-
- /* The following APIs regarding test app for compliance */
- @Override
- public boolean getProtocolMode(BluetoothDevice device, AttributionSource source) {
- HidHostService service = getService(source);
- if (service == null) {
- return false;
- }
- return service.getProtocolMode(device);
- }
-
- @Override
- public boolean virtualUnplug(BluetoothDevice device, AttributionSource source) {
- HidHostService service = getService(source);
- if (service == null) {
- return false;
- }
- return service.virtualUnplug(device);
- }
-
- @Override
- public boolean setProtocolMode(
- BluetoothDevice device, int protocolMode, AttributionSource source) {
- HidHostService service = getService(source);
- if (service == null) {
- return false;
- }
- return service.setProtocolMode(device, protocolMode);
- }
-
- @Override
- public boolean getReport(
- BluetoothDevice device,
- byte reportType,
- byte reportId,
- int bufferSize,
- AttributionSource source) {
- HidHostService service = getService(source);
- if (service == null) {
- return false;
- }
- return service.getReport(device, reportType, reportId, bufferSize);
- }
-
- @Override
- public boolean setReport(
- BluetoothDevice device, byte reportType, String report, AttributionSource source) {
- HidHostService service = getService(source);
- if (service == null) {
- return false;
- }
- return service.setReport(device, reportType, report);
- }
-
- @Override
- public boolean sendData(BluetoothDevice device, String report, AttributionSource source) {
- HidHostService service = getService(source);
- if (service == null) {
- return false;
- }
- return service.sendData(device, report);
- }
-
- @Override
- public boolean setIdleTime(
- BluetoothDevice device, byte idleTime, AttributionSource source) {
- HidHostService service = getService(source);
- if (service == null) {
- return false;
- }
- return service.setIdleTime(device, idleTime);
- }
-
- @Override
- public boolean getIdleTime(BluetoothDevice device, AttributionSource source) {
- HidHostService service = getService(source);
- if (service == null) {
- return false;
- }
- return service.getIdleTime(device);
- }
- }
- ;
-
// APIs
/**
@@ -983,7 +777,6 @@ public class HidHostService extends ProfileService {
return STATE_DISCONNECTED;
}
- @VisibleForTesting
List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
Log.d(TAG, "getDevicesMatchingConnectionStates()");
return mInputDevices.entrySet().stream()
@@ -1074,7 +867,6 @@ public class HidHostService extends ProfileService {
/**
* @see BluetoothHidHost#getPreferredTransport
*/
- @VisibleForTesting
int getPreferredTransport(BluetoothDevice device) {
Log.d(TAG, "getPreferredTransport: device=" + device);
@@ -1083,7 +875,6 @@ public class HidHostService extends ProfileService {
}
/* The following APIs regarding test app for compliance */
- @VisibleForTesting
boolean getProtocolMode(BluetoothDevice device) {
Log.d(TAG, "getProtocolMode: device=" + device);
int state = this.getConnectionState(device);
@@ -1095,7 +886,6 @@ public class HidHostService extends ProfileService {
return true;
}
- @VisibleForTesting
boolean virtualUnplug(BluetoothDevice device) {
Log.d(TAG, "virtualUnplug: device=" + device);
int state = this.getConnectionState(device);
@@ -1107,7 +897,6 @@ public class HidHostService extends ProfileService {
return true;
}
- @VisibleForTesting
boolean setProtocolMode(BluetoothDevice device, int protocolMode) {
Log.d(TAG, "setProtocolMode: device=" + device);
int state = this.getConnectionState(device);
@@ -1121,7 +910,6 @@ public class HidHostService extends ProfileService {
return true;
}
- @VisibleForTesting
boolean getReport(BluetoothDevice device, byte reportType, byte reportId, int bufferSize) {
Log.d(TAG, "getReport: device=" + device);
int state = this.getConnectionState(device);
@@ -1139,7 +927,6 @@ public class HidHostService extends ProfileService {
return true;
}
- @VisibleForTesting
boolean setReport(BluetoothDevice device, byte reportType, String report) {
Log.d(TAG, "setReport: device=" + device);
int state = this.getConnectionState(device);
@@ -1156,7 +943,6 @@ public class HidHostService extends ProfileService {
return true;
}
- @VisibleForTesting
boolean sendData(BluetoothDevice device, String report) {
Log.d(TAG, "sendData: device=" + device);
int state = this.getConnectionState(device);
@@ -1296,10 +1082,6 @@ public class HidHostService extends ProfileService {
return;
}
- if (newState == STATE_CONNECTED) {
- MetricsLogger.logProfileConnectionEvent(BluetoothMetricsProto.ProfileId.HID_HOST);
- }
-
mInputDevices.put(device, inputDevice);
broadcastConnectionState(device, transport, prevState, newState);
@@ -1398,8 +1180,9 @@ public class HidHostService extends ProfileService {
// Allow this connection only if the device is bonded. Any attempt to connect
// while bonding would potentially lead to an unauthorized connection.
if (bondState != BluetoothDevice.BOND_BONDED) {
- Log.w(TAG, "okToConnect: return false, device=" + device + " bondState="
- + bondState);
+ Log.w(
+ TAG,
+ "okToConnect: return false, device=" + device + " bondState=" + bondState);
return false;
}
}
diff --git a/android/app/src/com/android/bluetooth/hid/HidHostServiceBinder.java b/android/app/src/com/android/bluetooth/hid/HidHostServiceBinder.java
new file mode 100644
index 0000000000..3295c83f01
--- /dev/null
+++ b/android/app/src/com/android/bluetooth/hid/HidHostServiceBinder.java
@@ -0,0 +1,232 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.bluetooth.hid;
+
+import static android.Manifest.permission.BLUETOOTH_CONNECT;
+import static android.Manifest.permission.BLUETOOTH_PRIVILEGED;
+import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_UNKNOWN;
+import static android.bluetooth.BluetoothProfile.STATE_CONNECTED;
+import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTED;
+
+import android.annotation.RequiresPermission;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.IBluetoothHidHost;
+import android.content.AttributionSource;
+
+import com.android.bluetooth.Utils;
+import com.android.bluetooth.btservice.ProfileService.IProfileServiceBinder;
+
+import java.util.Collections;
+import java.util.List;
+
+class HidHostServiceBinder extends IBluetoothHidHost.Stub implements IProfileServiceBinder {
+ private static final String TAG = HidHostServiceBinder.class.getSimpleName();
+
+ private HidHostService mService;
+
+ HidHostServiceBinder(HidHostService svc) {
+ mService = svc;
+ }
+
+ @Override
+ public void cleanup() {
+ mService = null;
+ }
+
+ @RequiresPermission(BLUETOOTH_CONNECT)
+ private HidHostService getService(AttributionSource source) {
+ HidHostService service = mService;
+
+ if (Utils.isInstrumentationTestMode()) {
+ return service;
+ }
+
+ if (!Utils.checkServiceAvailable(service, TAG)
+ || !Utils.checkCallerIsSystemOrActiveOrManagedUser(service, TAG)
+ || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
+ return null;
+ }
+
+ return service;
+ }
+
+ @Override
+ public boolean connect(BluetoothDevice device, AttributionSource source) {
+ HidHostService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.connect(device);
+ }
+
+ @Override
+ public boolean disconnect(BluetoothDevice device, AttributionSource source) {
+ HidHostService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.disconnect(device);
+ }
+
+ @Override
+ public int getConnectionState(BluetoothDevice device, AttributionSource source) {
+ HidHostService service = getService(source);
+ if (service == null) {
+ return STATE_DISCONNECTED;
+ }
+ return service.getConnectionState(device);
+ }
+
+ @Override
+ public List<BluetoothDevice> getConnectedDevices(AttributionSource source) {
+ return getDevicesMatchingConnectionStates(new int[] {STATE_CONNECTED}, source);
+ }
+
+ @Override
+ public List<BluetoothDevice> getDevicesMatchingConnectionStates(
+ int[] states, AttributionSource source) {
+ HidHostService service = getService(source);
+ if (service == null) {
+ return Collections.emptyList();
+ }
+ return service.getDevicesMatchingConnectionStates(states);
+ }
+
+ @Override
+ public boolean setConnectionPolicy(
+ BluetoothDevice device, int connectionPolicy, AttributionSource source) {
+ HidHostService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.setConnectionPolicy(device, connectionPolicy);
+ }
+
+ @Override
+ public int getConnectionPolicy(BluetoothDevice device, AttributionSource source) {
+ HidHostService service = getService(source);
+ if (service == null) {
+ return CONNECTION_POLICY_UNKNOWN;
+ }
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.getConnectionPolicy(device);
+ }
+
+ @Override
+ public boolean setPreferredTransport(
+ BluetoothDevice device, int transport, AttributionSource source) {
+ HidHostService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.setPreferredTransport(device, transport);
+ }
+
+ @Override
+ public int getPreferredTransport(BluetoothDevice device, AttributionSource source) {
+ HidHostService service = getService(source);
+ if (service == null) {
+ return BluetoothDevice.TRANSPORT_AUTO;
+ }
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.getPreferredTransport(device);
+ }
+
+ /* The following APIs regarding test app for compliance */
+ @Override
+ public boolean getProtocolMode(BluetoothDevice device, AttributionSource source) {
+ HidHostService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+ return service.getProtocolMode(device);
+ }
+
+ @Override
+ public boolean virtualUnplug(BluetoothDevice device, AttributionSource source) {
+ HidHostService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+ return service.virtualUnplug(device);
+ }
+
+ @Override
+ public boolean setProtocolMode(
+ BluetoothDevice device, int protocolMode, AttributionSource source) {
+ HidHostService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+ return service.setProtocolMode(device, protocolMode);
+ }
+
+ @Override
+ public boolean getReport(
+ BluetoothDevice device,
+ byte reportType,
+ byte reportId,
+ int bufferSize,
+ AttributionSource source) {
+ HidHostService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+ return service.getReport(device, reportType, reportId, bufferSize);
+ }
+
+ @Override
+ public boolean setReport(
+ BluetoothDevice device, byte reportType, String report, AttributionSource source) {
+ HidHostService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+ return service.setReport(device, reportType, report);
+ }
+
+ @Override
+ public boolean sendData(BluetoothDevice device, String report, AttributionSource source) {
+ HidHostService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+ return service.sendData(device, report);
+ }
+
+ @Override
+ public boolean setIdleTime(BluetoothDevice device, byte idleTime, AttributionSource source) {
+ HidHostService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+ return service.setIdleTime(device, idleTime);
+ }
+
+ @Override
+ public boolean getIdleTime(BluetoothDevice device, AttributionSource source) {
+ HidHostService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+ return service.getIdleTime(device);
+ }
+}
diff --git a/android/app/src/com/android/bluetooth/le_audio/LeAudioService.java b/android/app/src/com/android/bluetooth/le_audio/LeAudioService.java
index 2379ffbd43..4f0d215e5b 100644
--- a/android/app/src/com/android/bluetooth/le_audio/LeAudioService.java
+++ b/android/app/src/com/android/bluetooth/le_audio/LeAudioService.java
@@ -27,6 +27,7 @@ import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTED;
import static android.bluetooth.IBluetoothLeAudio.LE_AUDIO_GROUP_ID_INVALID;
import static com.android.bluetooth.bass_client.BassConstants.INVALID_BROADCAST_ID;
+import static com.android.bluetooth.flags.Flags.doNotHardcodeTmapRoleMask;
import static com.android.bluetooth.flags.Flags.leaudioBigDependsOnAudioState;
import static com.android.bluetooth.flags.Flags.leaudioBroadcastApiManagePrimaryGroup;
import static com.android.bluetooth.flags.Flags.leaudioMonitorUnicastSourceWhenManagedByBroadcastDelegator;
@@ -35,7 +36,6 @@ import static com.android.modules.utils.build.SdkLevel.isAtLeastU;
import static java.util.Objects.requireNonNull;
-import android.annotation.RequiresPermission;
import android.annotation.SuppressLint;
import android.app.ActivityManager;
import android.bluetooth.BluetoothAdapter;
@@ -60,7 +60,6 @@ import android.bluetooth.le.IScannerCallback;
import android.bluetooth.le.ScanFilter;
import android.bluetooth.le.ScanResult;
import android.bluetooth.le.ScanSettings;
-import android.content.AttributionSource;
import android.content.Context;
import android.content.Intent;
import android.media.AudioDeviceCallback;
@@ -261,24 +260,49 @@ public class LeAudioService extends ProfileService {
mStateMachinesThread.start();
// Initialize Broadcast native interface
- if ((mAdapterService.getSupportedProfilesBitMask()
- & (1 << BluetoothProfile.LE_AUDIO_BROADCAST))
- != 0) {
- Log.i(TAG, "Init Le Audio broadcaster");
- LeAudioBroadcasterNativeInterface broadcastNativeInterface =
- requireNonNull(LeAudioBroadcasterNativeInterface.getInstance());
- broadcastNativeInterface.init();
- mLeAudioBroadcasterNativeInterface = Optional.of(broadcastNativeInterface);
- mTmapRoleMask =
- LeAudioTmapGattServer.TMAP_ROLE_FLAG_CG
- | LeAudioTmapGattServer.TMAP_ROLE_FLAG_UMS
- | LeAudioTmapGattServer.TMAP_ROLE_FLAG_BMS;
+ if (doNotHardcodeTmapRoleMask()) {
+ int mask = 0;
+ if (isProfileSupported(BluetoothProfile.LE_CALL_CONTROL)) {
+ // Table 3.5 of TMAP v1.0: CCP Server is mandatory for the TMAP CG role.
+ mask |= LeAudioTmapGattServer.TMAP_ROLE_FLAG_CG;
+ }
+ if (isProfileSupported(BluetoothProfile.MCP_SERVER)) {
+ // Table 3.5 of TMAP v1.0: MCP Server is mandatory for the TMAP UMS role.
+ mask |= LeAudioTmapGattServer.TMAP_ROLE_FLAG_UMS;
+ }
+ if (isProfileSupported(BluetoothProfile.LE_AUDIO_BROADCAST)) {
+ Log.i(TAG, "Init Le Audio broadcaster");
+ LeAudioBroadcasterNativeInterface broadcastNativeInterface =
+ requireNonNull(LeAudioBroadcasterNativeInterface.getInstance());
+ broadcastNativeInterface.init();
+ mLeAudioBroadcasterNativeInterface = Optional.of(broadcastNativeInterface);
+
+ mask |= LeAudioTmapGattServer.TMAP_ROLE_FLAG_BMS;
+ } else {
+ mLeAudioBroadcasterNativeInterface = Optional.empty();
+ Log.w(TAG, "Le Audio Broadcasts not supported.");
+ }
+ mTmapRoleMask = mask;
} else {
- mTmapRoleMask =
- LeAudioTmapGattServer.TMAP_ROLE_FLAG_CG
- | LeAudioTmapGattServer.TMAP_ROLE_FLAG_UMS;
- mLeAudioBroadcasterNativeInterface = Optional.empty();
- Log.w(TAG, "Le Audio Broadcasts not supported.");
+ if ((mAdapterService.getSupportedProfilesBitMask()
+ & (1 << BluetoothProfile.LE_AUDIO_BROADCAST))
+ != 0) {
+ Log.i(TAG, "Init Le Audio broadcaster");
+ LeAudioBroadcasterNativeInterface broadcastNativeInterface =
+ requireNonNull(LeAudioBroadcasterNativeInterface.getInstance());
+ broadcastNativeInterface.init();
+ mLeAudioBroadcasterNativeInterface = Optional.of(broadcastNativeInterface);
+ mTmapRoleMask =
+ LeAudioTmapGattServer.TMAP_ROLE_FLAG_CG
+ | LeAudioTmapGattServer.TMAP_ROLE_FLAG_UMS
+ | LeAudioTmapGattServer.TMAP_ROLE_FLAG_BMS;
+ } else {
+ mTmapRoleMask =
+ LeAudioTmapGattServer.TMAP_ROLE_FLAG_CG
+ | LeAudioTmapGattServer.TMAP_ROLE_FLAG_UMS;
+ mLeAudioBroadcasterNativeInterface = Optional.empty();
+ Log.w(TAG, "Le Audio Broadcasts not supported.");
+ }
}
mTmapStarted = registerTmap();
@@ -302,6 +326,15 @@ public class LeAudioService extends ProfileService {
}
}
+ private boolean isProfileSupported(int profile) {
+ return (mAdapterService.getSupportedProfilesBitMask() & (1 << profile)) != 0;
+ }
+
+ @VisibleForTesting
+ int getTmapRoleMask() {
+ return mTmapRoleMask;
+ }
+
private class LeAudioGroupDescriptor {
LeAudioGroupDescriptor(int groupId, boolean isInbandRingtoneEnabled) {
mGroupId = groupId;
@@ -586,7 +619,7 @@ public class LeAudioService extends ProfileService {
@Override
protected IProfileServiceBinder initBinder() {
- return new BluetoothLeAudioBinder(this);
+ return new LeAudioServiceBinder(this);
}
public static boolean isEnabled() {
@@ -770,12 +803,12 @@ public class LeAudioService extends ProfileService {
mLeAudioBroadcasterNativeInterface.ifPresent(i -> i.cleanup());
- try {
- mStateMachinesThread.quitSafely();
- mStateMachinesThread.join(SM_THREAD_JOIN_TIMEOUT_MS);
- } catch (InterruptedException e) {
- // Do not rethrow as we are shutting down anyway
- }
+ try {
+ mStateMachinesThread.quitSafely();
+ mStateMachinesThread.join(SM_THREAD_JOIN_TIMEOUT_MS);
+ } catch (InterruptedException e) {
+ // Do not rethrow as we are shutting down anyway
+ }
mAudioManager.unregisterAudioDeviceCallback(mAudioManagerAudioDeviceCallback);
@@ -1799,8 +1832,10 @@ public class LeAudioService extends ProfileService {
if (device != null && mActiveAudioInDevice != null) {
LeAudioDeviceDescriptor deviceDescriptor = getDeviceDescriptor(mActiveAudioInDevice);
if (deviceDescriptor == null) {
- Log.e(TAG, "updateActiveInDevice: No valid descriptor for device: "
- + mActiveAudioInDevice);
+ Log.e(
+ TAG,
+ "updateActiveInDevice: No valid descriptor for device: "
+ + mActiveAudioInDevice);
return false;
}
@@ -1865,8 +1900,10 @@ public class LeAudioService extends ProfileService {
if (device != null && mActiveAudioOutDevice != null) {
LeAudioDeviceDescriptor deviceDescriptor = getDeviceDescriptor(mActiveAudioOutDevice);
if (deviceDescriptor == null) {
- Log.e(TAG, "updateActiveOutDevice: No valid descriptor for device: "
- + mActiveAudioOutDevice);
+ Log.e(
+ TAG,
+ "updateActiveOutDevice: No valid descriptor for device: "
+ + mActiveAudioOutDevice);
return false;
}
@@ -2094,9 +2131,7 @@ public class LeAudioService extends ProfileService {
Log.d(TAG, "Scanner is not running (mScannerId=" + mScannerId + ")");
return;
}
- mAdapterService
- .getBluetoothScanController()
- .stopScanInternal(mScannerId);
+ mAdapterService.getBluetoothScanController().stopScanInternal(mScannerId);
mAdapterService.getBluetoothScanController().unregisterScannerInternal(mScannerId);
mScannerId = SCANNER_NOT_INITIALIZED;
@@ -2531,27 +2566,21 @@ public class LeAudioService extends ProfileService {
* broadcaster.
*/
if (isAnyBroadcastInStreamingState()) {
- LeAudioGroupDescriptor fallbackGroupDescriptor = getGroupDescriptor(groupId);
+ Log.w(TAG, "setActiveGroupWithDevice: Setting active device while broadcasting");
// If broadcast is ongoing and need to update unicast fallback active group
// we need to update the cached group id and skip changing the active device
- updateFallbackUnicastGroupIdForBroadcast(groupId);
+ if (!leaudioBroadcastApiManagePrimaryGroup()) {
+ updateFallbackUnicastGroupIdForBroadcast(groupId);
- if (!leaudioUseAudioRecordingListener()) {
- if (fallbackGroupDescriptor != null) {
- if (groupId == LE_AUDIO_GROUP_ID_INVALID) {
- /* In case of removing fallback unicast group, monitoring input device
- * should be removed from active devices.
- */
- updateActiveDevices(
- groupId,
- fallbackGroupDescriptor.mDirection,
- AUDIO_DIRECTION_INPUT_BIT,
- false,
- fallbackGroupDescriptor.mHasFallbackDeviceWhenGettingInactive,
- true);
- } else {
- if (mActiveAudioInDevice != null) {
+ if (!leaudioUseAudioRecordingListener()) {
+ LeAudioGroupDescriptor fallbackGroupDescriptor = getGroupDescriptor(groupId);
+
+ if (fallbackGroupDescriptor != null) {
+ if (groupId == LE_AUDIO_GROUP_ID_INVALID) {
+ /* In case of removing fallback unicast group, monitoring input device
+ * should be removed from active devices.
+ */
updateActiveDevices(
groupId,
fallbackGroupDescriptor.mDirection,
@@ -2559,6 +2588,17 @@ public class LeAudioService extends ProfileService {
false,
fallbackGroupDescriptor.mHasFallbackDeviceWhenGettingInactive,
true);
+ } else {
+ if (mActiveAudioInDevice != null) {
+ updateActiveDevices(
+ groupId,
+ fallbackGroupDescriptor.mDirection,
+ AUDIO_DIRECTION_INPUT_BIT,
+ false,
+ fallbackGroupDescriptor
+ .mHasFallbackDeviceWhenGettingInactive,
+ true);
+ }
}
}
}
@@ -3186,8 +3226,10 @@ public class LeAudioService extends ProfileService {
boolean ringtoneContextAvailable = false;
if (groupDescriptor.mAvailableContexts != null) {
- ringtoneContextAvailable = ((groupDescriptor.mAvailableContexts &
- BluetoothLeAudio.CONTEXT_TYPE_RINGTONE) != 0);
+ ringtoneContextAvailable =
+ ((groupDescriptor.mAvailableContexts
+ & BluetoothLeAudio.CONTEXT_TYPE_RINGTONE)
+ != 0);
}
/* Enables in-band ringtone only for the currently active device or
@@ -3684,9 +3726,7 @@ public class LeAudioService extends ProfileService {
} else if (isInitial) {
Log.i(
TAG,
- " New group "
- + groupId
- + " with no context types available");
+ " New group " + groupId + " with no context types available");
descriptor.mInactivatedDueToContextType = true;
}
return;
@@ -3754,9 +3794,7 @@ public class LeAudioService extends ProfileService {
{
LeAudioGroupDescriptor descriptor = getGroupDescriptor(groupId);
if (descriptor == null) {
- Log.e(
- TAG,
- "deviceDisconnected: no descriptors for group: " + groupId);
+ Log.e(TAG, "deviceDisconnected: no descriptors for group: " + groupId);
return;
}
@@ -4242,14 +4280,6 @@ public class LeAudioService extends ProfileService {
return;
}
- if (deviceDescriptor.mGroupId == LE_AUDIO_GROUP_ID_INVALID
- || getConnectedPeerDevices(deviceDescriptor.mGroupId).size() == 1) {
- // Log LE Audio connection event if we are the first device in a set
- // Or when the GroupId has not been found
- // MetricsLogger.logProfileConnectionEvent(
- // BluetoothMetricsProto.ProfileId.LE_AUDIO);
- }
-
LeAudioGroupDescriptor descriptor = getGroupDescriptor(deviceDescriptor.mGroupId);
if (descriptor != null) {
descriptor.mIsConnected = true;
@@ -4317,7 +4347,8 @@ public class LeAudioService extends ProfileService {
if (getConnectedPeerDevices(groupId).isEmpty()) {
descriptor.mIsConnected = false;
descriptor.mAutoActiveModeEnabled = true;
- descriptor.mAvailableContexts = Flags.leaudioUnicastNoAvailableContexts() ? null : 0;
+ descriptor.mAvailableContexts =
+ Flags.leaudioUnicastNoAvailableContexts() ? null : 0;
if (descriptor.isActive()) {
/* Notify Native layer */
removeActiveDevice(hasFallbackDevice);
@@ -5492,12 +5523,15 @@ public class LeAudioService extends ProfileService {
* device should be removed from active devices.
*/
int newDirection = AUDIO_DIRECTION_NONE;
- int oldDirection = oldFallbackGroupDescriptor != null
- ? oldFallbackGroupDescriptor.mDirection : AUDIO_DIRECTION_NONE;
+ int oldDirection =
+ oldFallbackGroupDescriptor != null
+ ? oldFallbackGroupDescriptor.mDirection
+ : AUDIO_DIRECTION_NONE;
boolean notifyAndUpdateInactiveOutDeviceOnly = false;
- boolean hasFallbackDeviceWhenGettingInactive = oldFallbackGroupDescriptor != null
- ? oldFallbackGroupDescriptor.mHasFallbackDeviceWhenGettingInactive
- : false;
+ boolean hasFallbackDeviceWhenGettingInactive =
+ oldFallbackGroupDescriptor != null
+ ? oldFallbackGroupDescriptor.mHasFallbackDeviceWhenGettingInactive
+ : false;
if (groupId != LE_AUDIO_GROUP_ID_INVALID) {
newDirection = AUDIO_DIRECTION_INPUT_BIT;
notifyAndUpdateInactiveOutDeviceOnly = true;
@@ -5691,525 +5725,6 @@ public class LeAudioService extends ProfileService {
}
}
- /** Binder object: must be a static class or memory leak may occur */
- @VisibleForTesting
- static class BluetoothLeAudioBinder extends IBluetoothLeAudio.Stub
- implements IProfileServiceBinder {
- private LeAudioService mService;
-
- BluetoothLeAudioBinder(LeAudioService svc) {
- mService = svc;
- }
-
- @Override
- public void cleanup() {
- mService = null;
- }
-
- @RequiresPermission(BLUETOOTH_CONNECT)
- private LeAudioService getServiceAndEnforceConnect(AttributionSource source) {
- requireNonNull(source);
- // Cache mService because it can change while getService is called
- LeAudioService service = mService;
-
- if (Utils.isInstrumentationTestMode()) {
- return service;
- }
-
- if (!Utils.checkServiceAvailable(service, TAG)
- || !Utils.checkCallerIsSystemOrActiveOrManagedUser(service, TAG)
- || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
- return null;
- }
- return service;
- }
-
- private LeAudioService getService() {
- // Cache mService because it can change while getService is called
- LeAudioService service = mService;
-
- if (Utils.isInstrumentationTestMode()) {
- return service;
- }
-
- if (!Utils.checkServiceAvailable(service, TAG)
- || !Utils.checkCallerIsSystemOrActiveOrManagedUser(service, TAG)) {
- return null;
- }
- return service;
- }
-
- @Override
- public boolean connect(BluetoothDevice device, AttributionSource source) {
- requireNonNull(device);
- requireNonNull(source);
-
- LeAudioService service = getServiceAndEnforceConnect(source);
- if (service == null) {
- return false;
- }
-
- return service.connect(device);
- }
-
- @Override
- public boolean disconnect(BluetoothDevice device, AttributionSource source) {
- requireNonNull(device);
- requireNonNull(source);
-
- LeAudioService service = getServiceAndEnforceConnect(source);
- if (service == null) {
- return false;
- }
-
- return service.disconnect(device);
- }
-
- @Override
- public List<BluetoothDevice> getConnectedDevices(AttributionSource source) {
- requireNonNull(source);
-
- LeAudioService service = getServiceAndEnforceConnect(source);
- if (service == null) {
- return Collections.emptyList();
- }
-
- return service.getConnectedDevices();
- }
-
- @Override
- public BluetoothDevice getConnectedGroupLeadDevice(int groupId, AttributionSource source) {
- requireNonNull(source);
-
- LeAudioService service = getServiceAndEnforceConnect(source);
- if (service == null) {
- return null;
- }
-
- return service.getConnectedGroupLeadDevice(groupId);
- }
-
- @Override
- public List<BluetoothDevice> getDevicesMatchingConnectionStates(
- int[] states, AttributionSource source) {
- requireNonNull(source);
-
- LeAudioService service = getServiceAndEnforceConnect(source);
- if (service == null) {
- return Collections.emptyList();
- }
-
- return service.getDevicesMatchingConnectionStates(states);
- }
-
- @Override
- public int getConnectionState(BluetoothDevice device, AttributionSource source) {
- requireNonNull(device);
- requireNonNull(source);
-
- LeAudioService service = getServiceAndEnforceConnect(source);
- if (service == null) {
- return STATE_DISCONNECTED;
- }
-
- return service.getConnectionState(device);
- }
-
- @Override
- public boolean setActiveDevice(BluetoothDevice device, AttributionSource source) {
- requireNonNull(source);
-
- LeAudioService service = getServiceAndEnforceConnect(source);
- if (service == null) {
- return false;
- }
-
- if (device == null) {
- return service.removeActiveDevice(true);
- } else {
- return service.setActiveDevice(device);
- }
- }
-
- @Override
- public List<BluetoothDevice> getActiveDevices(AttributionSource source) {
- requireNonNull(source);
-
- LeAudioService service = getServiceAndEnforceConnect(source);
- if (service == null) {
- return Collections.emptyList();
- }
-
- return service.getActiveDevices();
- }
-
- @Override
- public int getAudioLocation(BluetoothDevice device, AttributionSource source) {
- requireNonNull(device);
- requireNonNull(source);
-
- LeAudioService service = getServiceAndEnforceConnect(source);
- if (service == null) {
- return BluetoothLeAudio.AUDIO_LOCATION_INVALID;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- return service.getAudioLocation(device);
- }
-
- @Override
- public boolean isInbandRingtoneEnabled(AttributionSource source, int groupId) {
- requireNonNull(source);
-
- LeAudioService service = getServiceAndEnforceConnect(source);
- if (service == null) {
- return false;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- return service.isInbandRingtoneEnabled(groupId);
- }
-
- @Override
- public boolean setConnectionPolicy(
- BluetoothDevice device, int connectionPolicy, AttributionSource source) {
- requireNonNull(device);
- requireNonNull(source);
-
- LeAudioService service = getServiceAndEnforceConnect(source);
- if (service == null) {
- return false;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- return service.setConnectionPolicy(device, connectionPolicy);
- }
-
- @Override
- public int getConnectionPolicy(BluetoothDevice device, AttributionSource source) {
- requireNonNull(device);
- requireNonNull(source);
-
- LeAudioService service = getServiceAndEnforceConnect(source);
- if (service == null) {
- return CONNECTION_POLICY_UNKNOWN;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- return service.getConnectionPolicy(device);
- }
-
- @Override
- public void setCcidInformation(
- ParcelUuid userUuid, int ccid, int contextType, AttributionSource source) {
- requireNonNull(userUuid);
- requireNonNull(source);
-
- LeAudioService service = getServiceAndEnforceConnect(source);
- if (service == null) {
- return;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- service.setCcidInformation(userUuid, ccid, contextType);
- }
-
- @Override
- public int getGroupId(BluetoothDevice device, AttributionSource source) {
- requireNonNull(device);
- requireNonNull(source);
-
- LeAudioService service = getServiceAndEnforceConnect(source);
- if (service == null) {
- return LE_AUDIO_GROUP_ID_INVALID;
- }
-
- return service.getGroupId(device);
- }
-
- @Override
- public boolean groupAddNode(int groupId, BluetoothDevice device, AttributionSource source) {
- requireNonNull(device);
- requireNonNull(source);
-
- LeAudioService service = getServiceAndEnforceConnect(source);
- if (service == null) {
- return false;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- return service.groupAddNode(groupId, device);
- }
-
- @Override
- public void setInCall(boolean inCall, AttributionSource source) {
- requireNonNull(source);
-
- LeAudioService service = getServiceAndEnforceConnect(source);
- if (service == null) {
- return;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- service.setInCall(inCall);
- }
-
- @Override
- public void setInactiveForHfpHandover(
- BluetoothDevice hfpHandoverDevice, AttributionSource source) {
- requireNonNull(source);
-
- LeAudioService service = getServiceAndEnforceConnect(source);
- if (service == null) {
- return;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- service.setInactiveForHfpHandover(hfpHandoverDevice);
- }
-
- @Override
- public boolean groupRemoveNode(
- int groupId, BluetoothDevice device, AttributionSource source) {
- requireNonNull(device);
- requireNonNull(source);
-
- LeAudioService service = getServiceAndEnforceConnect(source);
- if (service == null) {
- return false;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- return service.groupRemoveNode(groupId, device);
- }
-
- @Override
- public void setVolume(int volume, AttributionSource source) {
- requireNonNull(source);
-
- LeAudioService service = getServiceAndEnforceConnect(source);
- if (service == null) {
- return;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- service.setVolume(volume);
- }
-
- @Override
- public void registerCallback(IBluetoothLeAudioCallback callback, AttributionSource source) {
- requireNonNull(callback);
- requireNonNull(source);
-
- LeAudioService service = getServiceAndEnforceConnect(source);
- if (service == null) {
- return;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- service.registerCallback(callback);
- }
-
- @Override
- public void unregisterCallback(
- IBluetoothLeAudioCallback callback, AttributionSource source) {
- requireNonNull(callback);
- requireNonNull(source);
-
- LeAudioService service = getServiceAndEnforceConnect(source);
- if (service == null) {
- return;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- service.unregisterCallback(callback);
- }
-
- @Override
- public void registerLeBroadcastCallback(
- IBluetoothLeBroadcastCallback callback, AttributionSource source) {
- requireNonNull(callback);
- requireNonNull(source);
-
- LeAudioService service = getServiceAndEnforceConnect(source);
- if (service == null) {
- return;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- service.registerLeBroadcastCallback(callback);
- }
-
- @Override
- public void unregisterLeBroadcastCallback(
- IBluetoothLeBroadcastCallback callback, AttributionSource source) {
- requireNonNull(callback);
- requireNonNull(source);
-
- LeAudioService service = getServiceAndEnforceConnect(source);
- if (service == null) {
- return;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- service.unregisterLeBroadcastCallback(callback);
- }
-
- @Override
- public void startBroadcast(
- BluetoothLeBroadcastSettings broadcastSettings, AttributionSource source) {
- LeAudioService service = getServiceAndEnforceConnect(source);
- if (service == null) {
- return;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- service.createBroadcast(broadcastSettings);
- }
-
- @Override
- public void stopBroadcast(int broadcastId, AttributionSource source) {
- LeAudioService service = getServiceAndEnforceConnect(source);
- if (service == null) {
- return;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- service.stopBroadcast(broadcastId);
- }
-
- @Override
- public void updateBroadcast(
- int broadcastId,
- BluetoothLeBroadcastSettings broadcastSettings,
- AttributionSource source) {
- LeAudioService service = getServiceAndEnforceConnect(source);
- if (service == null) {
- return;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- service.updateBroadcast(broadcastId, broadcastSettings);
- }
-
- @Override
- public boolean isPlaying(int broadcastId, AttributionSource source) {
- LeAudioService service = getServiceAndEnforceConnect(source);
- if (service == null) {
- return false;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- return service.isPlaying(broadcastId);
- }
-
- @Override
- public List<BluetoothLeBroadcastMetadata> getAllBroadcastMetadata(
- AttributionSource source) {
- LeAudioService service = getServiceAndEnforceConnect(source);
- if (service == null) {
- return Collections.emptyList();
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- return service.getAllBroadcastMetadata();
- }
-
- @Override
- public int getMaximumNumberOfBroadcasts() {
- LeAudioService service = getService();
- if (service == null) {
- return 0;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- return service.getMaximumNumberOfBroadcasts();
- }
-
- @Override
- public int getMaximumStreamsPerBroadcast() {
- LeAudioService service = getService();
- if (service == null) {
- return 0;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- return service.getMaximumStreamsPerBroadcast();
- }
-
- @Override
- public int getMaximumSubgroupsPerBroadcast() {
- LeAudioService service = getService();
- if (service == null) {
- return 0;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- return service.getMaximumSubgroupsPerBroadcast();
- }
-
- @Override
- public BluetoothLeAudioCodecStatus getCodecStatus(int groupId, AttributionSource source) {
- LeAudioService service = getServiceAndEnforceConnect(source);
- if (service == null) {
- return null;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- return service.getCodecStatus(groupId);
- }
-
- @Override
- public void setCodecConfigPreference(
- int groupId,
- BluetoothLeAudioCodecConfig inputCodecConfig,
- BluetoothLeAudioCodecConfig outputCodecConfig,
- AttributionSource source) {
- LeAudioService service = getServiceAndEnforceConnect(source);
- if (service == null) {
- return;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- service.setCodecConfigPreference(groupId, inputCodecConfig, outputCodecConfig);
- }
-
- @Override
- public void setBroadcastToUnicastFallbackGroup(int groupId, AttributionSource source) {
- LeAudioService service = getServiceAndEnforceConnect(source);
- if (service == null) {
- return;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- service.setBroadcastToUnicastFallbackGroup(groupId);
- }
-
- @Override
- public int getBroadcastToUnicastFallbackGroup(AttributionSource source) {
- LeAudioService service = getServiceAndEnforceConnect(source);
- if (service == null) {
- return LE_AUDIO_GROUP_ID_INVALID;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- return service.getBroadcastToUnicastFallbackGroup();
- }
-
- @Override
- public boolean isBroadcastActive(AttributionSource source) {
- LeAudioService service = getServiceAndEnforceConnect(source);
- if (service == null) {
- return false;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- return service.isBroadcastActive();
- }
- }
-
@Override
public void dump(StringBuilder sb) {
super.dump(sb);
diff --git a/android/app/src/com/android/bluetooth/le_audio/LeAudioServiceBinder.java b/android/app/src/com/android/bluetooth/le_audio/LeAudioServiceBinder.java
new file mode 100644
index 0000000000..e774c8fe33
--- /dev/null
+++ b/android/app/src/com/android/bluetooth/le_audio/LeAudioServiceBinder.java
@@ -0,0 +1,548 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.bluetooth.le_audio;
+
+import static android.Manifest.permission.BLUETOOTH_CONNECT;
+import static android.Manifest.permission.BLUETOOTH_PRIVILEGED;
+import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_UNKNOWN;
+import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTED;
+import static android.bluetooth.IBluetoothLeAudio.LE_AUDIO_GROUP_ID_INVALID;
+
+import static java.util.Objects.requireNonNull;
+
+import android.annotation.RequiresPermission;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothLeAudio;
+import android.bluetooth.BluetoothLeAudioCodecConfig;
+import android.bluetooth.BluetoothLeAudioCodecStatus;
+import android.bluetooth.BluetoothLeBroadcastMetadata;
+import android.bluetooth.BluetoothLeBroadcastSettings;
+import android.bluetooth.IBluetoothLeAudio;
+import android.bluetooth.IBluetoothLeAudioCallback;
+import android.bluetooth.IBluetoothLeBroadcastCallback;
+import android.content.AttributionSource;
+import android.os.ParcelUuid;
+
+import com.android.bluetooth.Utils;
+import com.android.bluetooth.btservice.ProfileService.IProfileServiceBinder;
+
+import java.util.Collections;
+import java.util.List;
+
+class LeAudioServiceBinder extends IBluetoothLeAudio.Stub implements IProfileServiceBinder {
+ private static final String TAG = LeAudioServiceBinder.class.getSimpleName();
+
+ private LeAudioService mService;
+
+ LeAudioServiceBinder(LeAudioService svc) {
+ mService = svc;
+ }
+
+ @Override
+ public void cleanup() {
+ mService = null;
+ }
+
+ private LeAudioService getService() {
+ LeAudioService service = mService;
+
+ if (Utils.isInstrumentationTestMode()) {
+ return service;
+ }
+
+ if (!Utils.checkServiceAvailable(service, TAG)
+ || !Utils.checkCallerIsSystemOrActiveOrManagedUser(service, TAG)) {
+ return null;
+ }
+ return service;
+ }
+
+ @RequiresPermission(BLUETOOTH_CONNECT)
+ private LeAudioService getServiceAndEnforceConnect(AttributionSource source) {
+ requireNonNull(source);
+ LeAudioService service = mService;
+
+ if (Utils.isInstrumentationTestMode()) {
+ return service;
+ }
+
+ if (!Utils.checkServiceAvailable(service, TAG)
+ || !Utils.checkCallerIsSystemOrActiveOrManagedUser(service, TAG)
+ || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
+ return null;
+ }
+ return service;
+ }
+
+ @Override
+ public boolean connect(BluetoothDevice device, AttributionSource source) {
+ requireNonNull(device);
+ requireNonNull(source);
+
+ LeAudioService service = getServiceAndEnforceConnect(source);
+ if (service == null) {
+ return false;
+ }
+
+ return service.connect(device);
+ }
+
+ @Override
+ public boolean disconnect(BluetoothDevice device, AttributionSource source) {
+ requireNonNull(device);
+ requireNonNull(source);
+
+ LeAudioService service = getServiceAndEnforceConnect(source);
+ if (service == null) {
+ return false;
+ }
+ return service.disconnect(device);
+ }
+
+ @Override
+ public List<BluetoothDevice> getConnectedDevices(AttributionSource source) {
+ requireNonNull(source);
+
+ LeAudioService service = getServiceAndEnforceConnect(source);
+ if (service == null) {
+ return Collections.emptyList();
+ }
+ return service.getConnectedDevices();
+ }
+
+ @Override
+ public BluetoothDevice getConnectedGroupLeadDevice(int groupId, AttributionSource source) {
+ requireNonNull(source);
+
+ LeAudioService service = getServiceAndEnforceConnect(source);
+ if (service == null) {
+ return null;
+ }
+ return service.getConnectedGroupLeadDevice(groupId);
+ }
+
+ @Override
+ public List<BluetoothDevice> getDevicesMatchingConnectionStates(
+ int[] states, AttributionSource source) {
+ requireNonNull(source);
+
+ LeAudioService service = getServiceAndEnforceConnect(source);
+ if (service == null) {
+ return Collections.emptyList();
+ }
+ return service.getDevicesMatchingConnectionStates(states);
+ }
+
+ @Override
+ public int getConnectionState(BluetoothDevice device, AttributionSource source) {
+ requireNonNull(device);
+ requireNonNull(source);
+
+ LeAudioService service = getServiceAndEnforceConnect(source);
+ if (service == null) {
+ return STATE_DISCONNECTED;
+ }
+ return service.getConnectionState(device);
+ }
+
+ @Override
+ public boolean setActiveDevice(BluetoothDevice device, AttributionSource source) {
+ requireNonNull(source);
+
+ LeAudioService service = getServiceAndEnforceConnect(source);
+ if (service == null) {
+ return false;
+ }
+
+ if (device == null) {
+ return service.removeActiveDevice(true);
+ } else {
+ return service.setActiveDevice(device);
+ }
+ }
+
+ @Override
+ public List<BluetoothDevice> getActiveDevices(AttributionSource source) {
+ requireNonNull(source);
+
+ LeAudioService service = getServiceAndEnforceConnect(source);
+ if (service == null) {
+ return Collections.emptyList();
+ }
+ return service.getActiveDevices();
+ }
+
+ @Override
+ public int getAudioLocation(BluetoothDevice device, AttributionSource source) {
+ requireNonNull(device);
+ requireNonNull(source);
+
+ LeAudioService service = getServiceAndEnforceConnect(source);
+ if (service == null) {
+ return BluetoothLeAudio.AUDIO_LOCATION_INVALID;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.getAudioLocation(device);
+ }
+
+ @Override
+ public boolean isInbandRingtoneEnabled(AttributionSource source, int groupId) {
+ requireNonNull(source);
+
+ LeAudioService service = getServiceAndEnforceConnect(source);
+ if (service == null) {
+ return false;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.isInbandRingtoneEnabled(groupId);
+ }
+
+ @Override
+ public boolean setConnectionPolicy(
+ BluetoothDevice device, int connectionPolicy, AttributionSource source) {
+ requireNonNull(device);
+ requireNonNull(source);
+
+ LeAudioService service = getServiceAndEnforceConnect(source);
+ if (service == null) {
+ return false;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.setConnectionPolicy(device, connectionPolicy);
+ }
+
+ @Override
+ public int getConnectionPolicy(BluetoothDevice device, AttributionSource source) {
+ requireNonNull(device);
+ requireNonNull(source);
+
+ LeAudioService service = getServiceAndEnforceConnect(source);
+ if (service == null) {
+ return CONNECTION_POLICY_UNKNOWN;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.getConnectionPolicy(device);
+ }
+
+ @Override
+ public void setCcidInformation(
+ ParcelUuid userUuid, int ccid, int contextType, AttributionSource source) {
+ requireNonNull(userUuid);
+ requireNonNull(source);
+
+ LeAudioService service = getServiceAndEnforceConnect(source);
+ if (service == null) {
+ return;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ service.setCcidInformation(userUuid, ccid, contextType);
+ }
+
+ @Override
+ public int getGroupId(BluetoothDevice device, AttributionSource source) {
+ requireNonNull(device);
+ requireNonNull(source);
+
+ LeAudioService service = getServiceAndEnforceConnect(source);
+ if (service == null) {
+ return LE_AUDIO_GROUP_ID_INVALID;
+ }
+ return service.getGroupId(device);
+ }
+
+ @Override
+ public boolean groupAddNode(int groupId, BluetoothDevice device, AttributionSource source) {
+ requireNonNull(device);
+ requireNonNull(source);
+
+ LeAudioService service = getServiceAndEnforceConnect(source);
+ if (service == null) {
+ return false;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.groupAddNode(groupId, device);
+ }
+
+ @Override
+ public void setInCall(boolean inCall, AttributionSource source) {
+ requireNonNull(source);
+
+ LeAudioService service = getServiceAndEnforceConnect(source);
+ if (service == null) {
+ return;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ service.setInCall(inCall);
+ }
+
+ @Override
+ public void setInactiveForHfpHandover(
+ BluetoothDevice hfpHandoverDevice, AttributionSource source) {
+ requireNonNull(source);
+
+ LeAudioService service = getServiceAndEnforceConnect(source);
+ if (service == null) {
+ return;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ service.setInactiveForHfpHandover(hfpHandoverDevice);
+ }
+
+ @Override
+ public boolean groupRemoveNode(int groupId, BluetoothDevice device, AttributionSource source) {
+ requireNonNull(device);
+ requireNonNull(source);
+
+ LeAudioService service = getServiceAndEnforceConnect(source);
+ if (service == null) {
+ return false;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.groupRemoveNode(groupId, device);
+ }
+
+ @Override
+ public void setVolume(int volume, AttributionSource source) {
+ requireNonNull(source);
+
+ LeAudioService service = getServiceAndEnforceConnect(source);
+ if (service == null) {
+ return;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ service.setVolume(volume);
+ }
+
+ @Override
+ public void registerCallback(IBluetoothLeAudioCallback callback, AttributionSource source) {
+ requireNonNull(callback);
+ requireNonNull(source);
+
+ LeAudioService service = getServiceAndEnforceConnect(source);
+ if (service == null) {
+ return;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ service.registerCallback(callback);
+ }
+
+ @Override
+ public void unregisterCallback(IBluetoothLeAudioCallback callback, AttributionSource source) {
+ requireNonNull(callback);
+ requireNonNull(source);
+
+ LeAudioService service = getServiceAndEnforceConnect(source);
+ if (service == null) {
+ return;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ service.unregisterCallback(callback);
+ }
+
+ @Override
+ public void registerLeBroadcastCallback(
+ IBluetoothLeBroadcastCallback callback, AttributionSource source) {
+ requireNonNull(callback);
+ requireNonNull(source);
+
+ LeAudioService service = getServiceAndEnforceConnect(source);
+ if (service == null) {
+ return;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ service.registerLeBroadcastCallback(callback);
+ }
+
+ @Override
+ public void unregisterLeBroadcastCallback(
+ IBluetoothLeBroadcastCallback callback, AttributionSource source) {
+ requireNonNull(callback);
+ requireNonNull(source);
+
+ LeAudioService service = getServiceAndEnforceConnect(source);
+ if (service == null) {
+ return;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ service.unregisterLeBroadcastCallback(callback);
+ }
+
+ @Override
+ public void startBroadcast(
+ BluetoothLeBroadcastSettings broadcastSettings, AttributionSource source) {
+ LeAudioService service = getServiceAndEnforceConnect(source);
+ if (service == null) {
+ return;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ service.createBroadcast(broadcastSettings);
+ }
+
+ @Override
+ public void stopBroadcast(int broadcastId, AttributionSource source) {
+ LeAudioService service = getServiceAndEnforceConnect(source);
+ if (service == null) {
+ return;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ service.stopBroadcast(broadcastId);
+ }
+
+ @Override
+ public void updateBroadcast(
+ int broadcastId,
+ BluetoothLeBroadcastSettings broadcastSettings,
+ AttributionSource source) {
+ LeAudioService service = getServiceAndEnforceConnect(source);
+ if (service == null) {
+ return;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ service.updateBroadcast(broadcastId, broadcastSettings);
+ }
+
+ @Override
+ public boolean isPlaying(int broadcastId, AttributionSource source) {
+ LeAudioService service = getServiceAndEnforceConnect(source);
+ if (service == null) {
+ return false;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.isPlaying(broadcastId);
+ }
+
+ @Override
+ public List<BluetoothLeBroadcastMetadata> getAllBroadcastMetadata(AttributionSource source) {
+ LeAudioService service = getServiceAndEnforceConnect(source);
+ if (service == null) {
+ return Collections.emptyList();
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.getAllBroadcastMetadata();
+ }
+
+ @Override
+ public int getMaximumNumberOfBroadcasts() {
+ LeAudioService service = getService();
+ if (service == null) {
+ return 0;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.getMaximumNumberOfBroadcasts();
+ }
+
+ @Override
+ public int getMaximumStreamsPerBroadcast() {
+ LeAudioService service = getService();
+ if (service == null) {
+ return 0;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.getMaximumStreamsPerBroadcast();
+ }
+
+ @Override
+ public int getMaximumSubgroupsPerBroadcast() {
+ LeAudioService service = getService();
+ if (service == null) {
+ return 0;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.getMaximumSubgroupsPerBroadcast();
+ }
+
+ @Override
+ public BluetoothLeAudioCodecStatus getCodecStatus(int groupId, AttributionSource source) {
+ LeAudioService service = getServiceAndEnforceConnect(source);
+ if (service == null) {
+ return null;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.getCodecStatus(groupId);
+ }
+
+ @Override
+ public void setCodecConfigPreference(
+ int groupId,
+ BluetoothLeAudioCodecConfig inputCodecConfig,
+ BluetoothLeAudioCodecConfig outputCodecConfig,
+ AttributionSource source) {
+ LeAudioService service = getServiceAndEnforceConnect(source);
+ if (service == null) {
+ return;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ service.setCodecConfigPreference(groupId, inputCodecConfig, outputCodecConfig);
+ }
+
+ @Override
+ public void setBroadcastToUnicastFallbackGroup(int groupId, AttributionSource source) {
+ LeAudioService service = getServiceAndEnforceConnect(source);
+ if (service == null) {
+ return;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ service.setBroadcastToUnicastFallbackGroup(groupId);
+ }
+
+ @Override
+ public int getBroadcastToUnicastFallbackGroup(AttributionSource source) {
+ LeAudioService service = getServiceAndEnforceConnect(source);
+ if (service == null) {
+ return LE_AUDIO_GROUP_ID_INVALID;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.getBroadcastToUnicastFallbackGroup();
+ }
+
+ @Override
+ public boolean isBroadcastActive(AttributionSource source) {
+ LeAudioService service = getServiceAndEnforceConnect(source);
+ if (service == null) {
+ return false;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.isBroadcastActive();
+ }
+}
diff --git a/android/app/src/com/android/bluetooth/le_audio/LeAudioTmapGattServer.java b/android/app/src/com/android/bluetooth/le_audio/LeAudioTmapGattServer.java
index 9f932470fb..0d503e85d3 100644
--- a/android/app/src/com/android/bluetooth/le_audio/LeAudioTmapGattServer.java
+++ b/android/app/src/com/android/bluetooth/le_audio/LeAudioTmapGattServer.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
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 0be2a7e299..07d7209b40 100644
--- a/android/app/src/com/android/bluetooth/le_scan/AppScanStats.java
+++ b/android/app/src/com/android/bluetooth/le_scan/AppScanStats.java
@@ -30,12 +30,10 @@ import android.os.BatteryStatsManager;
import android.os.Binder;
import android.os.WorkSource;
-import com.android.bluetooth.BluetoothMetricsProto;
import com.android.bluetooth.BluetoothStatsLog;
import com.android.bluetooth.Utils.TimeProvider;
import com.android.bluetooth.btservice.AdapterService;
import com.android.bluetooth.btservice.MetricsLogger;
-import com.android.bluetooth.flags.Flags;
import com.android.bluetooth.util.WorkSourceUtil;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
@@ -47,6 +45,7 @@ import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
+import java.util.Locale;
import java.util.Map;
import java.util.Objects;
@@ -64,9 +63,6 @@ class AppScanStats {
static final int LARGE_SCAN_TIME_GAP_MS = 24000;
- private static final ThreadLocal<DateFormat> DATE_FORMAT =
- ThreadLocal.withInitial(() -> new SimpleDateFormat("MM-dd HH:mm:ss"));
-
static WorkSourceUtil sRadioScanWorkSourceUtil;
static int sRadioScanType;
static int sRadioScanMode;
@@ -75,6 +71,7 @@ class AppScanStats {
static boolean sIsRadioStarted = false;
static boolean sIsScreenOn = false;
static int sRadioScanAppImportance = IMPORTANCE_CACHED;
+ @Nullable static String sRadioScanAttributionTag;
@GuardedBy("sLock")
static long sRadioStartTime = 0;
@@ -136,6 +133,10 @@ class AppScanStats {
this.appImportanceOnStart = appImportanceOnStart;
this.filterString = new StringBuilder();
}
+
+ private String getAttributionTag() {
+ return attributionTag != null ? attributionTag : "";
+ }
}
private final List<LastScan> mLastScans = new ArrayList<>();
@@ -193,20 +194,11 @@ class AppScanStats {
mTimeProvider = requireNonNull(timeProvider);
}
+ @Nullable
private synchronized LastScan getScanFromScannerId(int scannerId) {
return mOngoingScans.get(scannerId);
}
- private BluetoothMetricsProto.ScanEvent.Builder createBaseScanEvent(
- BluetoothMetricsProto.ScanEvent.ScanEventType type) {
- return BluetoothMetricsProto.ScanEvent.newBuilder()
- .setScanEventType(type)
- .setScanTechnologyType(
- BluetoothMetricsProto.ScanEvent.ScanTechnologyType.SCAN_TECH_TYPE_LE)
- .setEventTimeMillis(System.currentTimeMillis())
- .setInitiator(truncateAppName(mAppName));
- }
-
synchronized void addResult(int scannerId) {
LastScan scan = getScanFromScannerId(scannerId);
if (scan != null) {
@@ -318,11 +310,6 @@ class AppScanStats {
}
}
- BluetoothMetricsProto.ScanEvent scanEvent =
- createBaseScanEvent(BluetoothMetricsProto.ScanEvent.ScanEventType.SCAN_EVENT_START)
- .build();
- mScanController.addScanEvent(scanEvent);
-
if (!isScanning()) {
mScanStartTime = startTime;
}
@@ -362,12 +349,6 @@ class AppScanStats {
}
mLastScans.add(scan);
- BluetoothMetricsProto.ScanEvent scanEvent =
- createBaseScanEvent(BluetoothMetricsProto.ScanEvent.ScanEventType.SCAN_EVENT_STOP)
- .setNumberResults(scan.results)
- .build();
- mScanController.addScanEvent(scanEvent);
-
mTotalScanTime += scanDuration;
long activeDuration = scanDuration - scan.suspendDuration;
mTotalActiveTime += activeDuration;
@@ -413,23 +394,22 @@ class AppScanStats {
private void recordScanAppCountMetricsStart(LastScan scan) {
MetricsLogger logger = MetricsLogger.getInstance();
logger.cacheCount(BluetoothProtoEnums.LE_SCAN_COUNT_TOTAL_ENABLE, 1);
- if (Flags.bleScanAdvMetricsRedesign()) {
- logger.logAppScanStateChanged(
- mWorkSourceUtil.getUids(),
- mWorkSourceUtil.getTags(),
- true /* enabled */,
- scan.isFilterScan,
- scan.isCallbackScan,
- convertScanCallbackType(scan.scanCallbackType),
- convertScanType(scan),
- convertScanMode(scan.scanMode),
- scan.reportDelayMillis,
- 0 /* app_scan_duration_ms */,
- mOngoingScans.size(),
- sIsScreenOn,
- isAppDead,
- mAppImportance);
- }
+ logger.logAppScanStateChanged(
+ mWorkSourceUtil.getUids(),
+ mWorkSourceUtil.getTags(),
+ true /* enabled */,
+ scan.isFilterScan,
+ scan.isCallbackScan,
+ convertScanCallbackType(scan.scanCallbackType),
+ convertScanType(scan),
+ convertScanMode(scan.scanMode),
+ scan.reportDelayMillis,
+ 0 /* app_scan_duration_ms */,
+ mOngoingScans.size(),
+ sIsScreenOn,
+ isAppDead,
+ mAppImportance,
+ scan.getAttributionTag());
if (scan.isAutoBatchScan) {
logger.cacheCount(BluetoothProtoEnums.LE_SCAN_COUNT_AUTO_BATCH_ENABLE, 1);
} else if (scan.isBatchScan) {
@@ -446,23 +426,22 @@ class AppScanStats {
private void recordScanAppCountMetricsStop(LastScan scan) {
MetricsLogger logger = MetricsLogger.getInstance();
logger.cacheCount(BluetoothProtoEnums.LE_SCAN_COUNT_TOTAL_DISABLE, 1);
- if (Flags.bleScanAdvMetricsRedesign()) {
- logger.logAppScanStateChanged(
- mWorkSourceUtil.getUids(),
- mWorkSourceUtil.getTags(),
- false /* enabled */,
- scan.isFilterScan,
- scan.isCallbackScan,
- convertScanCallbackType(scan.scanCallbackType),
- convertScanType(scan),
- convertScanMode(scan.scanMode),
- scan.reportDelayMillis,
- scan.duration,
- mOngoingScans.size(),
- sIsScreenOn,
- isAppDead,
- mAppImportance);
- }
+ logger.logAppScanStateChanged(
+ mWorkSourceUtil.getUids(),
+ mWorkSourceUtil.getTags(),
+ false /* enabled */,
+ scan.isFilterScan,
+ scan.isCallbackScan,
+ convertScanCallbackType(scan.scanCallbackType),
+ convertScanType(scan),
+ convertScanMode(scan.scanMode),
+ scan.reportDelayMillis,
+ scan.duration,
+ mOngoingScans.size(),
+ sIsScreenOn,
+ isAppDead,
+ mAppImportance,
+ scan.getAttributionTag());
if (scan.isAutoBatchScan) {
logger.cacheCount(BluetoothProtoEnums.LE_SCAN_COUNT_AUTO_BATCH_DISABLE, 1);
} else if (scan.isBatchScan) {
@@ -539,46 +518,43 @@ class AppScanStats {
}
synchronized void recordScanTimeoutCountMetrics(int scannerId, long scanTimeoutMillis) {
- if (Flags.bleScanAdvMetricsRedesign()) {
- BluetoothStatsLog.write(
- BluetoothStatsLog.LE_SCAN_ABUSED,
- mWorkSourceUtil.getUids(),
- mWorkSourceUtil.getTags(),
- convertScanType(getScanFromScannerId(scannerId)),
- BluetoothStatsLog.LE_SCAN_ABUSED__LE_SCAN_ABUSE_REASON__REASON_SCAN_TIMEOUT,
- scanTimeoutMillis);
- }
+ BluetoothStatsLog.write(
+ BluetoothStatsLog.LE_SCAN_ABUSED,
+ mWorkSourceUtil.getUids(),
+ mWorkSourceUtil.getTags(),
+ convertScanType(getScanFromScannerId(scannerId)),
+ BluetoothStatsLog.LE_SCAN_ABUSED__LE_SCAN_ABUSE_REASON__REASON_SCAN_TIMEOUT,
+ scanTimeoutMillis,
+ getAttributionTagFromScannerId(scannerId));
MetricsLogger.getInstance()
.cacheCount(BluetoothProtoEnums.LE_SCAN_ABUSE_COUNT_SCAN_TIMEOUT, 1);
}
synchronized void recordHwFilterNotAvailableCountMetrics(
int scannerId, long numOfFilterSupported) {
- if (Flags.bleScanAdvMetricsRedesign()) {
- BluetoothStatsLog.write(
- BluetoothStatsLog.LE_SCAN_ABUSED,
- mWorkSourceUtil.getUids(),
- mWorkSourceUtil.getTags(),
- convertScanType(getScanFromScannerId(scannerId)),
- BluetoothStatsLog.LE_SCAN_ABUSED__LE_SCAN_ABUSE_REASON__REASON_HW_FILTER_NA,
- numOfFilterSupported);
- }
+ BluetoothStatsLog.write(
+ BluetoothStatsLog.LE_SCAN_ABUSED,
+ mWorkSourceUtil.getUids(),
+ mWorkSourceUtil.getTags(),
+ convertScanType(getScanFromScannerId(scannerId)),
+ BluetoothStatsLog.LE_SCAN_ABUSED__LE_SCAN_ABUSE_REASON__REASON_HW_FILTER_NA,
+ numOfFilterSupported,
+ getAttributionTagFromScannerId(scannerId));
MetricsLogger.getInstance()
.cacheCount(BluetoothProtoEnums.LE_SCAN_ABUSE_COUNT_HW_FILTER_NOT_AVAILABLE, 1);
}
synchronized void recordTrackingHwFilterNotAvailableCountMetrics(
int scannerId, long numOfTrackableAdv) {
- if (Flags.bleScanAdvMetricsRedesign()) {
- BluetoothStatsLog.write(
- BluetoothStatsLog.LE_SCAN_ABUSED,
- mWorkSourceUtil.getUids(),
- mWorkSourceUtil.getTags(),
- convertScanType(getScanFromScannerId(scannerId)),
- BluetoothStatsLog
- .LE_SCAN_ABUSED__LE_SCAN_ABUSE_REASON__REASON_TRACKING_HW_FILTER_NA,
- numOfTrackableAdv);
- }
+ BluetoothStatsLog.write(
+ BluetoothStatsLog.LE_SCAN_ABUSED,
+ mWorkSourceUtil.getUids(),
+ mWorkSourceUtil.getTags(),
+ convertScanType(getScanFromScannerId(scannerId)),
+ BluetoothStatsLog
+ .LE_SCAN_ABUSED__LE_SCAN_ABUSE_REASON__REASON_TRACKING_HW_FILTER_NA,
+ numOfTrackableAdv,
+ getAttributionTagFromScannerId(scannerId));
MetricsLogger.getInstance()
.cacheCount(
BluetoothProtoEnums.LE_SCAN_ABUSE_COUNT_TRACKING_HW_FILTER_NOT_AVAILABLE,
@@ -610,6 +586,7 @@ class AppScanStats {
sRadioScanIntervalMs = scanIntervalMs;
sIsRadioStarted = true;
sRadioScanAppImportance = stats.mAppImportance;
+ sRadioScanAttributionTag = stats.getAttributionTagFromScannerId(scannerId);
}
return true;
}
@@ -620,10 +597,6 @@ class AppScanStats {
return false;
}
recordScanRadioDurationMetrics(timeProvider);
- if (!Flags.bleScanAdvMetricsRedesign()) {
- sRadioStartTime = 0;
- sIsRadioStarted = false;
- }
}
return true;
}
@@ -639,20 +612,19 @@ class AppScanStats {
double scanWeight = getScanWeight(sRadioScanMode) * 0.01;
long weightedDuration = (long) (radioScanDuration * scanWeight);
- if (Flags.bleScanAdvMetricsRedesign()) {
- logger.logRadioScanStopped(
- getRadioScanUids(),
- getRadioScanTags(),
- sRadioScanType,
- convertScanMode(sRadioScanMode),
- sRadioScanIntervalMs,
- sRadioScanWindowMs,
- sIsScreenOn,
- radioScanDuration,
- sRadioScanAppImportance);
- sRadioStartTime = 0;
- sIsRadioStarted = false;
- }
+ logger.logRadioScanStopped(
+ getRadioScanUids(),
+ getRadioScanTags(),
+ sRadioScanType,
+ convertScanMode(sRadioScanMode),
+ sRadioScanIntervalMs,
+ sRadioScanWindowMs,
+ sIsScreenOn,
+ radioScanDuration,
+ sRadioScanAppImportance,
+ getRadioScanAttributionTag());
+ sRadioStartTime = 0;
+ sIsRadioStarted = false;
if (weightedDuration > 0) {
logger.cacheCount(BluetoothProtoEnums.LE_SCAN_RADIO_DURATION_REGULAR, weightedDuration);
if (sIsScreenOn) {
@@ -683,6 +655,12 @@ class AppScanStats {
}
}
+ private static String getRadioScanAttributionTag() {
+ synchronized (sLock) {
+ return sRadioScanAttributionTag != null ? sRadioScanAttributionTag : "";
+ }
+ }
+
@GuardedBy("sLock")
private static void recordScreenOnOffMetrics(boolean isScreenOn) {
if (isScreenOn) {
@@ -716,15 +694,14 @@ class AppScanStats {
if (!sIsRadioStarted) {
return;
}
- if (Flags.bleScanAdvMetricsRedesign()) {
- BluetoothStatsLog.write(
- BluetoothStatsLog.LE_SCAN_RESULT_RECEIVED,
- getRadioScanUids(),
- getRadioScanTags(),
- 1 /* num_results */,
- BluetoothStatsLog.LE_SCAN_RESULT_RECEIVED__LE_SCAN_TYPE__SCAN_TYPE_REGULAR,
- sIsScreenOn);
- }
+ BluetoothStatsLog.write(
+ BluetoothStatsLog.LE_SCAN_RESULT_RECEIVED,
+ getRadioScanUids(),
+ getRadioScanTags(),
+ 1 /* num_results */,
+ BluetoothStatsLog.LE_SCAN_RESULT_RECEIVED__LE_SCAN_TYPE__SCAN_TYPE_REGULAR,
+ sIsScreenOn,
+ getRadioScanAttributionTag());
MetricsLogger logger = MetricsLogger.getInstance();
logger.cacheCount(BluetoothProtoEnums.LE_SCAN_RESULTS_COUNT_REGULAR, 1);
if (sIsScreenOn) {
@@ -740,15 +717,14 @@ class AppScanStats {
synchronized (sLock) {
isScreenOn = sIsScreenOn;
}
- if (Flags.bleScanAdvMetricsRedesign()) {
- BluetoothStatsLog.write(
- BluetoothStatsLog.LE_SCAN_RESULT_RECEIVED,
- getRadioScanUids(),
- getRadioScanTags(),
- numRecords,
- BluetoothStatsLog.LE_SCAN_RESULT_RECEIVED__LE_SCAN_TYPE__SCAN_TYPE_BATCH,
- sIsScreenOn);
- }
+ BluetoothStatsLog.write(
+ BluetoothStatsLog.LE_SCAN_RESULT_RECEIVED,
+ getRadioScanUids(),
+ getRadioScanTags(),
+ numRecords,
+ BluetoothStatsLog.LE_SCAN_RESULT_RECEIVED__LE_SCAN_TYPE__SCAN_TYPE_BATCH,
+ sIsScreenOn,
+ getRadioScanAttributionTag());
MetricsLogger logger = MetricsLogger.getInstance();
logger.cacheCount(BluetoothProtoEnums.LE_SCAN_RESULTS_COUNT_BATCH_BUNDLE, 1);
logger.cacheCount(BluetoothProtoEnums.LE_SCAN_RESULTS_COUNT_BATCH, numRecords);
@@ -853,22 +829,9 @@ class AppScanStats {
< LARGE_SCAN_TIME_GAP_MS);
}
- // This function truncates the app name for privacy reasons. Apps with
- // four part package names or more get truncated to three parts, and apps
- // with three part package names names get truncated to two. Apps with two
- // or less package names names are untouched.
- // Examples: one.two.three.four => one.two.three
- // one.two.three => one.two
- private static String truncateAppName(String name) {
- String initiator = name;
- String[] nameSplit = initiator.split("\\.");
- if (nameSplit.length > 3) {
- initiator = nameSplit[0] + "." + nameSplit[1] + "." + nameSplit[2];
- } else if (nameSplit.length == 3) {
- initiator = nameSplit[0] + "." + nameSplit[1];
- }
-
- return initiator;
+ private String getAttributionTagFromScannerId(int scannerId) {
+ LastScan scan = getScanFromScannerId(scannerId);
+ return scan == null ? "" : scan.getAttributionTag();
}
private static String filterToStringWithoutNullParam(ScanFilter filter) {
@@ -963,6 +926,8 @@ class AppScanStats {
@SuppressWarnings("JavaUtilDate") // TODO: b/365629730 -- prefer Instant or LocalDate
public synchronized void dumpToString(StringBuilder sb) {
+ DateFormat dateFormat = new SimpleDateFormat("MM-dd HH:mm:ss", Locale.ROOT);
+
long currentTime = System.currentTimeMillis();
long currTime = mTimeProvider.elapsedRealtime();
long scanDuration = 0;
@@ -1070,7 +1035,7 @@ class AppScanStats {
for (int i = 0; i < mLastScans.size(); i++) {
LastScan scan = mLastScans.get(i);
Date timestamp = new Date(currentTime - currTime + scan.timestamp);
- sb.append("\n ").append(DATE_FORMAT.get().format(timestamp)).append(" - ");
+ sb.append("\n ").append(dateFormat.format(timestamp)).append(" - ");
sb.append(scan.duration).append("ms ");
if (scan.isOpportunisticScan) {
sb.append("Opp ");
@@ -1133,7 +1098,7 @@ class AppScanStats {
sb.append("\n Ongoing scans :");
for (LastScan scan : mOngoingScans.values()) {
Date timestamp = new Date(currentTime - currTime + scan.timestamp);
- sb.append("\n ").append(DATE_FORMAT.get().format(timestamp)).append(" - ");
+ sb.append("\n ").append(dateFormat.format(timestamp)).append(" - ");
sb.append((currTime - scan.timestamp)).append("ms ");
if (scan.isOpportunisticScan) {
sb.append("Opp ");
diff --git a/android/app/src/com/android/bluetooth/le_scan/BatchScanThrottler.java b/android/app/src/com/android/bluetooth/le_scan/BatchScanThrottler.java
index 3cc06fffe4..3569745bd5 100644
--- a/android/app/src/com/android/bluetooth/le_scan/BatchScanThrottler.java
+++ b/android/app/src/com/android/bluetooth/le_scan/BatchScanThrottler.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2025 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/android/app/src/com/android/bluetooth/le_scan/PeriodicScanNativeInterface.java b/android/app/src/com/android/bluetooth/le_scan/PeriodicScanNativeInterface.java
index 0d06dfb0cc..71558cae4c 100644
--- a/android/app/src/com/android/bluetooth/le_scan/PeriodicScanNativeInterface.java
+++ b/android/app/src/com/android/bluetooth/le_scan/PeriodicScanNativeInterface.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 The Android Open Source Project
+ * Copyright (C) 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.
diff --git a/android/app/src/com/android/bluetooth/le_scan/ScanBinder.java b/android/app/src/com/android/bluetooth/le_scan/ScanBinder.java
deleted file mode 100644
index 2e905e087a..0000000000
--- a/android/app/src/com/android/bluetooth/le_scan/ScanBinder.java
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Copyright (C) 2025 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.bluetooth.le_scan;
-
-import android.app.PendingIntent;
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.IBluetoothScan;
-import android.bluetooth.le.IPeriodicAdvertisingCallback;
-import android.bluetooth.le.IScannerCallback;
-import android.bluetooth.le.ScanFilter;
-import android.bluetooth.le.ScanResult;
-import android.bluetooth.le.ScanSettings;
-import android.content.AttributionSource;
-import android.os.WorkSource;
-import android.util.Log;
-
-import java.util.List;
-
-class ScanBinder extends IBluetoothScan.Stub {
- private static final String TAG = ScanBinder.class.getSimpleName();
-
- private ScanController mScanController;
-
- ScanBinder(ScanController scanController) {
- mScanController = scanController;
- }
-
- @Override
- public void registerScanner(
- IScannerCallback callback, WorkSource workSource, AttributionSource source) {
- ScanController scanController = getScanController();
- if (scanController == null) {
- return;
- }
- scanController.registerScanner(callback, workSource, source);
- }
-
- @Override
- public void unregisterScanner(int scannerId, AttributionSource source) {
- ScanController scanController = getScanController();
- if (scanController == null) {
- return;
- }
- scanController.unregisterScanner(scannerId, source);
- }
-
- @Override
- public void startScan(
- int scannerId,
- ScanSettings settings,
- List<ScanFilter> filters,
- AttributionSource source) {
- ScanController scanController = getScanController();
- if (scanController == null) {
- return;
- }
- scanController.startScan(scannerId, settings, filters, source);
- }
-
- @Override
- public void startScanForIntent(
- PendingIntent intent,
- ScanSettings settings,
- List<ScanFilter> filters,
- AttributionSource source) {
- ScanController scanController = getScanController();
- if (scanController == null) {
- return;
- }
- scanController.registerPiAndStartScan(intent, settings, filters, source);
- }
-
- @Override
- public void stopScan(int scannerId, AttributionSource source) {
- ScanController scanController = getScanController();
- if (scanController == null) {
- return;
- }
- scanController.stopScan(scannerId, source);
- }
-
- @Override
- public void stopScanForIntent(PendingIntent intent, AttributionSource source) {
- ScanController scanController = getScanController();
- if (scanController == null) {
- return;
- }
- scanController.stopScan(intent, source);
- }
-
- @Override
- public void flushPendingBatchResults(int scannerId, AttributionSource source) {
- ScanController scanController = getScanController();
- if (scanController == null) {
- return;
- }
- scanController.flushPendingBatchResults(scannerId, source);
- }
-
- @Override
- public void registerSync(
- ScanResult scanResult,
- int skip,
- int timeout,
- IPeriodicAdvertisingCallback callback,
- AttributionSource source) {
- ScanController scanController = getScanController();
- if (scanController == null) {
- return;
- }
- scanController.registerSync(scanResult, skip, timeout, callback, source);
- }
-
- @Override
- public void unregisterSync(IPeriodicAdvertisingCallback callback, AttributionSource source) {
- ScanController scanController = getScanController();
- if (scanController == null) {
- return;
- }
- scanController.unregisterSync(callback, source);
- }
-
- @Override
- public void transferSync(
- BluetoothDevice bda, int serviceData, int syncHandle, AttributionSource source) {
- ScanController scanController = getScanController();
- if (scanController == null) {
- return;
- }
- scanController.transferSync(bda, serviceData, syncHandle, source);
- }
-
- @Override
- public void transferSetInfo(
- BluetoothDevice bda,
- int serviceData,
- int advHandle,
- IPeriodicAdvertisingCallback callback,
- AttributionSource source) {
- ScanController scanController = getScanController();
- if (scanController == null) {
- return;
- }
- scanController.transferSetInfo(bda, serviceData, advHandle, callback, source);
- }
-
- @Override
- public int numHwTrackFiltersAvailable(AttributionSource source) {
- ScanController scanController = getScanController();
- if (scanController == null) {
- return 0;
- }
- return scanController.numHwTrackFiltersAvailable(source);
- }
-
- void clearScanController() {
- mScanController = null;
- }
-
- private ScanController getScanController() {
- ScanController controller = mScanController;
- if (controller != null && controller.isAvailable()) {
- return controller;
- }
- Log.e(TAG, "getScanController() - ScanController requested, but not available!");
- return null;
- }
-}
diff --git a/android/app/src/com/android/bluetooth/le_scan/ScanBinder.kt b/android/app/src/com/android/bluetooth/le_scan/ScanBinder.kt
new file mode 100644
index 0000000000..bd5bd6e111
--- /dev/null
+++ b/android/app/src/com/android/bluetooth/le_scan/ScanBinder.kt
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.bluetooth.le_scan
+
+import android.app.PendingIntent
+import android.bluetooth.BluetoothDevice
+import android.bluetooth.IBluetoothScan
+import android.bluetooth.le.IPeriodicAdvertisingCallback
+import android.bluetooth.le.IScannerCallback
+import android.bluetooth.le.ScanFilter
+import android.bluetooth.le.ScanResult
+import android.bluetooth.le.ScanSettings
+import android.content.AttributionSource
+import android.os.WorkSource
+import android.util.Log
+
+class ScanBinder(private val mScanController: ScanController) : IBluetoothScan.Stub() {
+
+ companion object {
+ private val TAG = ScanBinder::class.java.simpleName
+ }
+
+ @Volatile private var mIsAvailable = true
+
+ fun cleanup() {
+ mIsAvailable = false
+ }
+
+ private fun getScanController(): ScanController? {
+ if (mIsAvailable) {
+ return mScanController
+ } else {
+ Log.e(TAG, "getScanController() - ScanController requested, but not available!")
+ return null
+ }
+ }
+
+ override fun registerScanner(
+ callback: IScannerCallback,
+ workSource: WorkSource?,
+ source: AttributionSource,
+ ) {
+ getScanController()?.let { scanController ->
+ scanController.registerScanner(callback, workSource, source)
+ }
+ }
+
+ override fun unregisterScanner(scannerId: Int, source: AttributionSource) {
+ getScanController()?.let { scanController ->
+ scanController.unregisterScanner(scannerId, source)
+ }
+ }
+
+ override fun startScan(
+ scannerId: Int,
+ settings: ScanSettings?,
+ filters: List<ScanFilter>?,
+ source: AttributionSource,
+ ) {
+ getScanController()?.let { scanController ->
+ scanController.startScan(scannerId, settings, filters, source)
+ }
+ }
+
+ override fun startScanForIntent(
+ intent: PendingIntent,
+ settings: ScanSettings?,
+ filters: List<ScanFilter>?,
+ source: AttributionSource,
+ ) {
+ getScanController()?.let { scanController ->
+ scanController.registerPiAndStartScan(intent, settings, filters, source)
+ }
+ }
+
+ override fun stopScan(scannerId: Int, source: AttributionSource) {
+ getScanController()?.let { scanController -> scanController.stopScan(scannerId, source) }
+ }
+
+ override fun stopScanForIntent(intent: PendingIntent, source: AttributionSource) {
+ getScanController()?.let { scanController -> scanController.stopScan(intent, source) }
+ }
+
+ override fun flushPendingBatchResults(scannerId: Int, source: AttributionSource) {
+ getScanController()?.let { scanController ->
+ scanController.flushPendingBatchResults(scannerId, source)
+ }
+ }
+
+ override fun registerSync(
+ scanResult: ScanResult,
+ skip: Int,
+ timeout: Int,
+ callback: IPeriodicAdvertisingCallback,
+ source: AttributionSource,
+ ) {
+ getScanController()?.let { scanController ->
+ scanController.registerSync(scanResult, skip, timeout, callback, source)
+ }
+ }
+
+ override fun unregisterSync(callback: IPeriodicAdvertisingCallback, source: AttributionSource) {
+ getScanController()?.let { scanController ->
+ scanController.unregisterSync(callback, source)
+ }
+ }
+
+ override fun transferSync(
+ device: BluetoothDevice,
+ serviceData: Int,
+ syncHandle: Int,
+ source: AttributionSource,
+ ) {
+ getScanController()?.let { scanController ->
+ scanController.transferSync(device, serviceData, syncHandle, source)
+ }
+ }
+
+ override fun transferSetInfo(
+ device: BluetoothDevice,
+ serviceData: Int,
+ advHandle: Int,
+ callback: IPeriodicAdvertisingCallback,
+ source: AttributionSource,
+ ) {
+ getScanController()?.let { scanController ->
+ scanController.transferSetInfo(device, serviceData, advHandle, callback, source)
+ }
+ }
+
+ override fun numHwTrackFiltersAvailable(source: AttributionSource): Int {
+ return getScanController()?.let { scanController ->
+ scanController.numHwTrackFiltersAvailable(source)
+ } ?: 0
+ }
+}
diff --git a/android/app/src/com/android/bluetooth/le_scan/ScanController.java b/android/app/src/com/android/bluetooth/le_scan/ScanController.java
index 6e1678d97e..2fc20d8314 100644
--- a/android/app/src/com/android/bluetooth/le_scan/ScanController.java
+++ b/android/app/src/com/android/bluetooth/le_scan/ScanController.java
@@ -22,6 +22,7 @@ import static android.Manifest.permission.UPDATE_DEVICE_STATS;
import static android.bluetooth.BluetoothUtils.extractBytes;
import static com.android.bluetooth.Utils.checkCallerTargetSdk;
+import static com.android.bluetooth.Utils.checkScanPermissionForDataDelivery;
import static com.android.bluetooth.flags.Flags.leaudioBassScanWithInternalScanController;
import static java.util.Objects.requireNonNull;
@@ -60,7 +61,6 @@ import android.provider.DeviceConfig;
import android.text.format.DateUtils;
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;
@@ -73,11 +73,9 @@ import libcore.util.HexEncoding;
import com.google.protobuf.ByteString;
-import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
-import java.util.Deque;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -96,7 +94,6 @@ public class ScanController {
// Batch scan related constants.
private static final int TRUNCATED_RESULT_SIZE = 11;
- private static final int NUM_SCAN_EVENTS_KEPT = 20;
// onFoundLost related constants
@VisibleForTesting static final int ADVT_STATE_ONFOUND = 0;
@@ -122,10 +119,6 @@ public class ScanController {
}
};
- /** Internal list of scan events to use with the proto */
- private final Deque<BluetoothMetricsProto.ScanEvent> mScanEvents =
- new ArrayDeque<>(NUM_SCAN_EVENTS_KEPT);
-
private final Map<Integer, Integer> mFilterIndexToMsftAdvMonitorMap = new HashMap<>();
private final Object mTestModeLock = new Object();
@@ -143,7 +136,6 @@ public class ScanController {
private volatile boolean mTestModeEnabled = false;
private ScannerMap mScannerMap = new ScannerMap();
- private boolean mIsAvailable;
private Handler mTestModeHandler;
public ScanController(AdapterService adapterService) {
@@ -171,7 +163,6 @@ public class ScanController {
};
mMainLooper = adapterService.getMainLooper();
mBinder = new ScanBinder(this);
- mIsAvailable = true;
mScanThread = new HandlerThread("BluetoothScanManager");
mScanThread.start();
mAppOps = mAdapterService.getSystemService(AppOpsManager.class);
@@ -188,18 +179,13 @@ public class ScanController {
public void cleanup() {
Log.i(TAG, "Cleanup ScanController");
- mIsAvailable = false;
- mBinder.clearScanController();
+ mBinder.cleanup();
mScanThread.quitSafely();
mScannerMap.clear();
mScanManager.cleanup();
mPeriodicScanManager.cleanup();
}
- boolean isAvailable() {
- return mIsAvailable;
- }
-
ScannerMap getScannerMap() {
return mScannerMap;
}
@@ -1097,8 +1083,7 @@ public class ScanController {
@RequiresPermission(BLUETOOTH_SCAN)
void registerScanner(
IScannerCallback callback, WorkSource workSource, AttributionSource source) {
- if (!Utils.checkScanPermissionForDataDelivery(
- mAdapterService, source, "ScanController registerScanner")) {
+ if (!checkScanPermissionForDataDelivery(mAdapterService, source, TAG, "registerScanner")) {
return;
}
@@ -1131,8 +1116,8 @@ public class ScanController {
@RequiresPermission(BLUETOOTH_SCAN)
void unregisterScanner(int scannerId, AttributionSource source) {
- if (!Utils.checkScanPermissionForDataDelivery(
- mAdapterService, source, "ScanController unregisterScanner")) {
+ if (!checkScanPermissionForDataDelivery(
+ mAdapterService, source, TAG, "unregisterScanner")) {
return;
}
@@ -1178,7 +1163,7 @@ public class ScanController {
List<ScanFilter> filters,
AttributionSource source) {
Log.d(TAG, "Start scan with filters");
- if (!Utils.checkScanPermissionForDataDelivery(mAdapterService, source, "Starting scan.")) {
+ if (!checkScanPermissionForDataDelivery(mAdapterService, source, TAG, "startScan")) {
return;
}
@@ -1270,7 +1255,8 @@ public class ScanController {
List<ScanFilter> filters,
AttributionSource source) {
Log.d(TAG, "Start scan with filters, for PendingIntent");
- if (!Utils.checkScanPermissionForDataDelivery(mAdapterService, source, "Starting scan.")) {
+ if (!checkScanPermissionForDataDelivery(
+ mAdapterService, source, TAG, "registerPiAndStartScan")) {
return;
}
@@ -1374,8 +1360,8 @@ public class ScanController {
@RequiresPermission(BLUETOOTH_SCAN)
void flushPendingBatchResults(int scannerId, AttributionSource source) {
- if (!Utils.checkScanPermissionForDataDelivery(
- mAdapterService, source, "ScanController flushPendingBatchResults")) {
+ if (!checkScanPermissionForDataDelivery(
+ mAdapterService, source, TAG, "flushPendingBatchResults")) {
return;
}
flushPendingBatchResultsInternal(scannerId);
@@ -1388,8 +1374,7 @@ public class ScanController {
@RequiresPermission(BLUETOOTH_SCAN)
void stopScan(int scannerId, AttributionSource source) {
- if (!Utils.checkScanPermissionForDataDelivery(
- mAdapterService, source, "ScanController stopScan")) {
+ if (!checkScanPermissionForDataDelivery(mAdapterService, source, TAG, "stopScan")) {
return;
}
stopScanInternal(scannerId);
@@ -1411,8 +1396,7 @@ public class ScanController {
@RequiresPermission(BLUETOOTH_SCAN)
void stopScan(PendingIntent intent, AttributionSource source) {
- if (!Utils.checkScanPermissionForDataDelivery(
- mAdapterService, source, "ScanController stopScan")) {
+ if (!checkScanPermissionForDataDelivery(mAdapterService, source, TAG, "stopScan")) {
return;
}
stopScanInternal(intent);
@@ -1441,8 +1425,7 @@ public class ScanController {
int timeout,
IPeriodicAdvertisingCallback callback,
AttributionSource source) {
- if (!Utils.checkScanPermissionForDataDelivery(
- mAdapterService, source, "ScanController registerSync")) {
+ if (!checkScanPermissionForDataDelivery(mAdapterService, source, TAG, "registerSync")) {
return;
}
mPeriodicScanManager.startSync(scanResult, skip, timeout, callback);
@@ -1450,8 +1433,7 @@ public class ScanController {
@RequiresPermission(BLUETOOTH_SCAN)
void unregisterSync(IPeriodicAdvertisingCallback callback, AttributionSource source) {
- if (!Utils.checkScanPermissionForDataDelivery(
- mAdapterService, source, "ScanController unregisterSync")) {
+ if (!checkScanPermissionForDataDelivery(mAdapterService, source, TAG, "unregisterSync")) {
return;
}
mPeriodicScanManager.stopSync(callback);
@@ -1460,8 +1442,7 @@ public class ScanController {
@RequiresPermission(BLUETOOTH_SCAN)
void transferSync(
BluetoothDevice bda, int serviceData, int syncHandle, AttributionSource source) {
- if (!Utils.checkScanPermissionForDataDelivery(
- mAdapterService, source, "ScanController transferSync")) {
+ if (!checkScanPermissionForDataDelivery(mAdapterService, source, TAG, "transferSync")) {
return;
}
mPeriodicScanManager.transferSync(bda, serviceData, syncHandle);
@@ -1474,8 +1455,7 @@ public class ScanController {
int advHandle,
IPeriodicAdvertisingCallback callback,
AttributionSource source) {
- if (!Utils.checkScanPermissionForDataDelivery(
- mAdapterService, source, "ScanController transferSetInfo")) {
+ if (!checkScanPermissionForDataDelivery(mAdapterService, source, TAG, "transferSetInfo")) {
return;
}
mPeriodicScanManager.transferSetInfo(bda, serviceData, advHandle, callback);
@@ -1483,8 +1463,8 @@ public class ScanController {
@RequiresPermission(BLUETOOTH_SCAN)
int numHwTrackFiltersAvailable(AttributionSource source) {
- if (!Utils.checkScanPermissionForDataDelivery(
- mAdapterService, source, "ScanController numHwTrackFiltersAvailable")) {
+ if (!checkScanPermissionForDataDelivery(
+ mAdapterService, source, TAG, "numHwTrackFiltersAvailable")) {
return 0;
}
return (mAdapterService.getTotalNumOfTrackableAdvertisements()
@@ -1656,15 +1636,6 @@ public class ScanController {
}
}
- void addScanEvent(BluetoothMetricsProto.ScanEvent event) {
- synchronized (mScanEvents) {
- if (mScanEvents.size() == NUM_SCAN_EVENTS_KEPT) {
- mScanEvents.remove();
- }
- mScanEvents.add(event);
- }
- }
-
public void dumpRegisterId(StringBuilder sb) {
sb.append(" Scanner:\n");
mScannerMap.dumpApps(sb, ProfileService::println);
@@ -1674,10 +1645,4 @@ public class ScanController {
sb.append("GATT Scanner Map\n");
mScannerMap.dump(sb);
}
-
- public void dumpProto(BluetoothMetricsProto.BluetoothLog.Builder builder) {
- synchronized (mScanEvents) {
- builder.addAllScanEvent(mScanEvents);
- }
- }
}
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 cf6ef7d928..e31bd36bbb 100644
--- a/android/app/src/com/android/bluetooth/le_scan/ScanManager.java
+++ b/android/app/src/com/android/bluetooth/le_scan/ScanManager.java
@@ -1292,18 +1292,6 @@ public class ScanManager {
&& client.mSettings.getScanMode() != ScanSettings.SCAN_MODE_OPPORTUNISTIC) {
Log.d(TAG, "start gattClientScanNative from startRegularScan()");
mNativeInterface.gattClientScan(true);
- if (!Flags.bleScanAdvMetricsRedesign()) {
- if (client.mStats != null
- && !AppScanStats.recordScanRadioStart(
- client.mSettings.getScanMode(),
- client.mScannerId,
- client.mStats,
- getScanWindowMillis(client.mSettings),
- getScanIntervalMillis(client.mSettings),
- mTimeProvider)) {
- Log.w(TAG, "Scan radio already started");
- }
- }
}
}
diff --git a/android/app/src/com/android/bluetooth/le_scan/ScanObjectsFactory.java b/android/app/src/com/android/bluetooth/le_scan/ScanObjectsFactory.java
index cca760249f..c7f3605588 100644
--- a/android/app/src/com/android/bluetooth/le_scan/ScanObjectsFactory.java
+++ b/android/app/src/com/android/bluetooth/le_scan/ScanObjectsFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 The Android Open Source Project
+ * Copyright (C) 2024 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.
diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapAppParams.java b/android/app/src/com/android/bluetooth/map/BluetoothMapAppParams.java
index 71342f0e29..ea34b20875 100644
--- a/android/app/src/com/android/bluetooth/map/BluetoothMapAppParams.java
+++ b/android/app/src/com/android/bluetooth/map/BluetoothMapAppParams.java
@@ -29,6 +29,7 @@ import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
+import java.util.Locale;
/** This class encapsulates the appParams needed for MAP. */
// Next tag value for ContentProfileErrorReportUtils.report(): 41
@@ -1225,7 +1226,7 @@ public class BluetoothMapAppParams {
@SuppressWarnings("JavaUtilDate") // TODO: b/365629730 -- prefer Instant or LocalDate
public String getFilterPeriodBeginString() {
- SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmss");
+ SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmss", Locale.ROOT);
Date date = new Date(mFilterPeriodBegin);
return format.format(date); // Format to YYYYMMDDTHHMMSS local time
}
@@ -1236,7 +1237,7 @@ public class BluetoothMapAppParams {
@SuppressWarnings("JavaUtilDate") // TODO: b/365629730 -- prefer Instant or LocalDate
public void setFilterPeriodBegin(String filterPeriodBegin) throws ParseException {
- SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmss");
+ SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmss", Locale.ROOT);
Date date = format.parse(filterPeriodBegin);
this.mFilterPeriodBegin = date.getTime();
}
@@ -1247,7 +1248,7 @@ public class BluetoothMapAppParams {
@SuppressWarnings("JavaUtilDate") // TODO: b/365629730 -- prefer Instant or LocalDate
public String getFilterLastActivityBeginString() {
- SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmss");
+ SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmss", Locale.ROOT);
Date date = new Date(mFilterPeriodBegin);
return format.format(date); // Format to YYYYMMDDTHHMMSS local time
}
@@ -1258,7 +1259,7 @@ public class BluetoothMapAppParams {
@SuppressWarnings("JavaUtilDate") // TODO: b/365629730 -- prefer Instant or LocalDate
public void setFilterLastActivityBegin(String filterPeriodBegin) throws ParseException {
- SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmss");
+ SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmss", Locale.ROOT);
Date date = format.parse(filterPeriodBegin);
this.mFilterPeriodBegin = date.getTime();
}
@@ -1273,7 +1274,7 @@ public class BluetoothMapAppParams {
@SuppressWarnings("JavaUtilDate") // TODO: b/365629730 -- prefer Instant or LocalDate
public String getFilterLastActivityEndString() {
- SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmss");
+ SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmss", Locale.ROOT);
Date date = new Date(mFilterPeriodEnd);
return format.format(date); // Format to YYYYMMDDTHHMMSS local time
}
@@ -1284,14 +1285,14 @@ public class BluetoothMapAppParams {
@SuppressWarnings("JavaUtilDate") // TODO: b/365629730 -- prefer Instant or LocalDate
public void setFilterPeriodEnd(String filterPeriodEnd) throws ParseException {
- SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmss");
+ SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmss", Locale.ROOT);
Date date = format.parse(filterPeriodEnd);
this.mFilterPeriodEnd = date.getTime();
}
@SuppressWarnings("JavaUtilDate") // TODO: b/365629730 -- prefer Instant or LocalDate
public String getFilterPeriodEndString() {
- SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmss");
+ SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmss", Locale.ROOT);
Date date = new Date(mFilterPeriodEnd);
return format.format(date); // Format to YYYYMMDDTHHMMSS local time
}
@@ -1302,7 +1303,7 @@ public class BluetoothMapAppParams {
@SuppressWarnings("JavaUtilDate") // TODO: b/365629730 -- prefer Instant or LocalDate
public void setFilterLastActivityEnd(String filterPeriodEnd) throws ParseException {
- SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmss");
+ SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmss", Locale.ROOT);
Date date = format.parse(filterPeriodEnd);
this.mFilterPeriodEnd = date.getTime();
}
@@ -1507,7 +1508,7 @@ public class BluetoothMapAppParams {
@SuppressWarnings("JavaUtilDate") // TODO: b/365629730 -- prefer Instant or LocalDate
public String getLastActivityString() {
- SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmssZ");
+ SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmssZ", Locale.ROOT);
Date date = new Date(mLastActivity);
return format.format(date); // Format to YYYYMMDDTHHMMSS local time
}
@@ -1518,7 +1519,7 @@ public class BluetoothMapAppParams {
@SuppressWarnings("JavaUtilDate") // TODO: b/365629730 -- prefer Instant or LocalDate
public void setLastActivity(String lastActivity) throws ParseException {
- SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmssZ");
+ SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmssZ", Locale.ROOT);
Date date = format.parse(lastActivity);
this.mLastActivity = date.getTime();
}
@@ -1755,7 +1756,7 @@ public class BluetoothMapAppParams {
@SuppressWarnings("JavaUtilDate") // TODO: b/365629730 -- prefer Instant or LocalDate
public String getMseTimeString() {
- SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmssZ");
+ SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmssZ", Locale.ROOT);
Date date = new Date(getMseTime());
return format.format(date); // Format to YYYYMMDDTHHMMSS±hhmm UTC time ± offset
}
@@ -1766,7 +1767,7 @@ public class BluetoothMapAppParams {
@SuppressWarnings("JavaUtilDate") // TODO: b/365629730 -- prefer Instant or LocalDate
public void setMseTime(String mseTime) throws ParseException {
- SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmssZ");
+ SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmssZ", Locale.ROOT);
Date date = format.parse(mseTime);
this.mMseTime = date.getTime();
}
diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapConvoContactElement.java b/android/app/src/com/android/bluetooth/map/BluetoothMapConvoContactElement.java
index d22dfe24b1..c5642c54a5 100644
--- a/android/app/src/com/android/bluetooth/map/BluetoothMapConvoContactElement.java
+++ b/android/app/src/com/android/bluetooth/map/BluetoothMapConvoContactElement.java
@@ -26,6 +26,7 @@ import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
+import java.util.Locale;
import java.util.Objects;
// Next tag value for ContentProfileErrorReportUtils.report(): 1
@@ -158,7 +159,7 @@ public class BluetoothMapConvoContactElement
@SuppressWarnings("JavaUtilDate") // TODO: b/365629730 -- prefer Instant or LocalDate
public String getLastActivityString() {
- SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmss");
+ SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmss", Locale.ROOT);
Date date = new Date(mLastActivity);
return format.format(date); // Format to YYYYMMDDTHHMMSS local time
}
@@ -169,7 +170,7 @@ public class BluetoothMapConvoContactElement
@SuppressWarnings("JavaUtilDate") // TODO: b/365629730 -- prefer Instant or LocalDate
public void setLastActivity(String lastActivity) throws ParseException {
- SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmss");
+ SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmss", Locale.ROOT);
Date date = format.parse(lastActivity);
this.mLastActivity = date.getTime();
}
diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapConvoListingElement.java b/android/app/src/com/android/bluetooth/map/BluetoothMapConvoListingElement.java
index 0abe14aa2c..f3a7a0a79a 100644
--- a/android/app/src/com/android/bluetooth/map/BluetoothMapConvoListingElement.java
+++ b/android/app/src/com/android/bluetooth/map/BluetoothMapConvoListingElement.java
@@ -34,6 +34,7 @@ import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
+import java.util.Locale;
import java.util.Objects;
// Next tag value for ContentProfileErrorReportUtils.report(): 2
@@ -146,7 +147,7 @@ public class BluetoothMapConvoListingElement
@SuppressWarnings("JavaUtilDate") // TODO: b/365629730 -- prefer Instant or LocalDate
public String getLastActivityString() {
- SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmss");
+ SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmss", Locale.ROOT);
Date date = new Date(mLastActivity);
return format.format(date); // Format to YYYYMMDDTHHMMSS local time
}
@@ -159,7 +160,7 @@ public class BluetoothMapConvoListingElement
@SuppressWarnings("JavaUtilDate") // TODO: b/365629730 -- prefer Instant or LocalDate
public void setLastActivity(String lastActivity) throws ParseException {
// TODO: Encode with time-zone if MCE requests it
- SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmss");
+ SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmss", Locale.ROOT);
Date date = format.parse(lastActivity);
this.mLastActivity = date.getTime();
}
diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapMessageListingElement.java b/android/app/src/com/android/bluetooth/map/BluetoothMapMessageListingElement.java
index 87dd614f18..c8ee05a5bd 100644
--- a/android/app/src/com/android/bluetooth/map/BluetoothMapMessageListingElement.java
+++ b/android/app/src/com/android/bluetooth/map/BluetoothMapMessageListingElement.java
@@ -22,6 +22,7 @@ import org.xmlpull.v1.XmlSerializer;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
+import java.util.Locale;
public class BluetoothMapMessageListingElement
implements Comparable<BluetoothMapMessageListingElement> {
@@ -78,7 +79,7 @@ public class BluetoothMapMessageListingElement
public String getDateTimeString() {
/* TODO: if the feature bit mask of the client supports it, add the time-zone
* (as for MSETime) */
- SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmss");
+ SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmss", Locale.ROOT);
Date date = new Date(mDateTime);
return format.format(date); // Format to YYYYMMDDTHHMMSS local time
}
diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapService.java b/android/app/src/com/android/bluetooth/map/BluetoothMapService.java
index 962bfb4421..b43af84dcc 100644
--- a/android/app/src/com/android/bluetooth/map/BluetoothMapService.java
+++ b/android/app/src/com/android/bluetooth/map/BluetoothMapService.java
@@ -18,7 +18,6 @@ package com.android.bluetooth.map;
import static android.Manifest.permission.BLUETOOTH_CONNECT;
import static android.Manifest.permission.BLUETOOTH_PRIVILEGED;
import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
-import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_UNKNOWN;
import static android.bluetooth.BluetoothProfile.STATE_CONNECTED;
import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTED;
@@ -33,9 +32,7 @@ import android.bluetooth.BluetoothMap;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothProtoEnums;
import android.bluetooth.BluetoothUuid;
-import android.bluetooth.IBluetoothMap;
import android.bluetooth.SdpMnsRecord;
-import android.content.AttributionSource;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -55,12 +52,10 @@ import android.telephony.TelephonyManager;
import android.util.Log;
import android.util.SparseArray;
-import com.android.bluetooth.BluetoothMetricsProto;
import com.android.bluetooth.BluetoothStatsLog;
import com.android.bluetooth.R;
import com.android.bluetooth.Utils;
import com.android.bluetooth.btservice.AdapterService;
-import com.android.bluetooth.btservice.MetricsLogger;
import com.android.bluetooth.btservice.ProfileService;
import com.android.bluetooth.btservice.storage.DatabaseManager;
import com.android.bluetooth.content_profiles.ContentProfileErrorReportUtils;
@@ -68,7 +63,6 @@ import com.android.internal.annotations.VisibleForTesting;
import java.io.IOException;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.HashMap;
import java.util.List;
@@ -151,7 +145,6 @@ public class BluetoothMapService extends ProfileService {
private static BluetoothMapService sBluetoothMapService;
-
private static final ParcelUuid[] MAP_UUIDS = {
BluetoothUuid.MAP, BluetoothUuid.MNS,
};
@@ -707,15 +700,12 @@ public class BluetoothMapService extends ProfileService {
@Override
protected IProfileServiceBinder initBinder() {
- return new BluetoothMapBinder(this);
+ return new BluetoothMapServiceBinder(this);
}
/**
- * Get the current instance of {@link BluetoothMapService}
- *
* @return current instance of {@link BluetoothMapService}
*/
- @VisibleForTesting
public static synchronized BluetoothMapService getBluetoothMapService() {
if (sBluetoothMapService == null) {
Log.w(TAG, "getBluetoothMapService(): service is null");
@@ -959,7 +949,6 @@ public class BluetoothMapService extends ProfileService {
} else if (mPermission == BluetoothDevice.ACCESS_ALLOWED) {
// Signal to the service that we have a incoming connection.
sendConnectMessage(masInst.getMasId());
- MetricsLogger.logProfileConnectionEvent(BluetoothMetricsProto.ProfileId.MAP);
}
return true;
}
@@ -1196,227 +1185,6 @@ public class BluetoothMapService extends ProfileService {
}
}
- // Binder object: Must be static class or memory leak may occur
-
- /**
- * This class implements the IBluetoothMap interface - or actually it validates the
- * preconditions for calling the actual functionality in the MapService, and calls it.
- */
- @VisibleForTesting
- static class BluetoothMapBinder extends IBluetoothMap.Stub implements IProfileServiceBinder {
- private BluetoothMapService mService;
-
- BluetoothMapBinder(BluetoothMapService service) {
- mService = service;
- }
-
- @Override
- public synchronized void cleanup() {
- mService = null;
- }
-
- @RequiresPermission(BLUETOOTH_CONNECT)
- private BluetoothMapService getService(AttributionSource source) {
- // Cache mService because it can change while getService is called
- BluetoothMapService service = mService;
-
- if (Utils.isInstrumentationTestMode()) {
- return service;
- }
-
- if (!Utils.checkServiceAvailable(service, TAG)
- || !Utils.checkCallerIsSystemOrActiveOrManagedUser(service, TAG)
- || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
- return null;
- }
- return service;
- }
-
- @Override
- public int getState(AttributionSource source) {
- Log.v(TAG, "getState()");
- try {
- BluetoothMapService service = getService(source);
- if (service == null) {
- return BluetoothMap.STATE_DISCONNECTED;
- }
-
- return service.getState();
- } catch (RuntimeException e) {
- ContentProfileErrorReportUtils.report(
- BluetoothProfile.MAP,
- BluetoothProtoEnums.BLUETOOTH_MAP_SERVICE,
- BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION,
- 16);
- throw e;
- }
- }
-
- @Override
- public BluetoothDevice getClient(AttributionSource source) {
- Log.v(TAG, "getClient()");
- try {
- BluetoothMapService service = getService(source);
- if (service == null) {
- Log.v(TAG, "getClient() - no service - returning " + null);
- return null;
- }
- BluetoothDevice client = service.getRemoteDevice();
- Log.v(TAG, "getClient() - returning " + client);
- return client;
- } catch (RuntimeException e) {
- ContentProfileErrorReportUtils.report(
- BluetoothProfile.MAP,
- BluetoothProtoEnums.BLUETOOTH_MAP_SERVICE,
- BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION,
- 17);
- throw e;
- }
- }
-
- @Override
- public boolean isConnected(BluetoothDevice device, AttributionSource source) {
- Log.v(TAG, "isConnected()");
- try {
- BluetoothMapService service = getService(source);
- if (service == null) {
- return false;
- }
-
- return service.getConnectionState(device) == STATE_CONNECTED;
- } catch (RuntimeException e) {
- ContentProfileErrorReportUtils.report(
- BluetoothProfile.MAP,
- BluetoothProtoEnums.BLUETOOTH_MAP_SERVICE,
- BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION,
- 18);
- throw e;
- }
- }
-
- @Override
- public boolean disconnect(BluetoothDevice device, AttributionSource source) {
- Log.v(TAG, "disconnect()");
- try {
- BluetoothMapService service = getService(source);
- if (service == null) {
- return false;
- }
-
- service.disconnect(device);
- return true;
- } catch (RuntimeException e) {
- ContentProfileErrorReportUtils.report(
- BluetoothProfile.MAP,
- BluetoothProtoEnums.BLUETOOTH_MAP_SERVICE,
- BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION,
- 19);
- throw e;
- }
- }
-
- @Override
- public List<BluetoothDevice> getConnectedDevices(AttributionSource source) {
- Log.v(TAG, "getConnectedDevices()");
- try {
- BluetoothMapService service = getService(source);
- if (service == null) {
- return Collections.emptyList();
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- return service.getConnectedDevices();
- } catch (RuntimeException e) {
- ContentProfileErrorReportUtils.report(
- BluetoothProfile.MAP,
- BluetoothProtoEnums.BLUETOOTH_MAP_SERVICE,
- BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION,
- 20);
- throw e;
- }
- }
-
- @Override
- public List<BluetoothDevice> getDevicesMatchingConnectionStates(
- int[] states, AttributionSource source) {
- Log.v(TAG, "getDevicesMatchingConnectionStates()");
- try {
- BluetoothMapService service = getService(source);
- if (service == null) {
- return Collections.emptyList();
- }
-
- return service.getDevicesMatchingConnectionStates(states);
- } catch (RuntimeException e) {
- ContentProfileErrorReportUtils.report(
- BluetoothProfile.MAP,
- BluetoothProtoEnums.BLUETOOTH_MAP_SERVICE,
- BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION,
- 21);
- throw e;
- }
- }
-
- @Override
- public int getConnectionState(BluetoothDevice device, AttributionSource source) {
- Log.v(TAG, "getConnectionState()");
- try {
- BluetoothMapService service = getService(source);
- if (service == null) {
- return STATE_DISCONNECTED;
- }
-
- return service.getConnectionState(device);
- } catch (RuntimeException e) {
- ContentProfileErrorReportUtils.report(
- BluetoothProfile.MAP,
- BluetoothProtoEnums.BLUETOOTH_MAP_SERVICE,
- BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION,
- 22);
- throw e;
- }
- }
-
- @Override
- public boolean setConnectionPolicy(
- BluetoothDevice device, int connectionPolicy, AttributionSource source) {
- try {
- BluetoothMapService service = getService(source);
- if (service == null) {
- return false;
- }
-
- return service.setConnectionPolicy(device, connectionPolicy);
- } catch (RuntimeException e) {
- ContentProfileErrorReportUtils.report(
- BluetoothProfile.MAP,
- BluetoothProtoEnums.BLUETOOTH_MAP_SERVICE,
- BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION,
- 23);
- throw e;
- }
- }
-
- @Override
- public int getConnectionPolicy(BluetoothDevice device, AttributionSource source) {
- try {
- BluetoothMapService service = getService(source);
- if (service == null) {
- return CONNECTION_POLICY_UNKNOWN;
- }
-
- return service.getConnectionPolicy(device);
- } catch (RuntimeException e) {
- ContentProfileErrorReportUtils.report(
- BluetoothProfile.MAP,
- BluetoothProtoEnums.BLUETOOTH_MAP_SERVICE,
- BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION,
- 24);
- throw e;
- }
- }
- }
-
@Override
public void dump(StringBuilder sb) {
super.dump(sb);
diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapServiceBinder.java b/android/app/src/com/android/bluetooth/map/BluetoothMapServiceBinder.java
new file mode 100644
index 0000000000..0706bcab6f
--- /dev/null
+++ b/android/app/src/com/android/bluetooth/map/BluetoothMapServiceBinder.java
@@ -0,0 +1,251 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.bluetooth.map;
+
+import static android.Manifest.permission.BLUETOOTH_CONNECT;
+import static android.Manifest.permission.BLUETOOTH_PRIVILEGED;
+import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_UNKNOWN;
+import static android.bluetooth.BluetoothProfile.STATE_CONNECTED;
+import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTED;
+
+import android.annotation.RequiresPermission;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothMap;
+import android.bluetooth.BluetoothProfile;
+import android.bluetooth.BluetoothProtoEnums;
+import android.bluetooth.IBluetoothMap;
+import android.content.AttributionSource;
+import android.util.Log;
+
+import com.android.bluetooth.BluetoothStatsLog;
+import com.android.bluetooth.Utils;
+import com.android.bluetooth.btservice.ProfileService.IProfileServiceBinder;
+import com.android.bluetooth.content_profiles.ContentProfileErrorReportUtils;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * This class implements the IBluetoothMap interface - or actually it validates the preconditions
+ * for calling the actual functionality in the MapService, and calls it.
+ */
+class BluetoothMapServiceBinder extends IBluetoothMap.Stub implements IProfileServiceBinder {
+ private static final String TAG = BluetoothMapServiceBinder.class.getSimpleName();
+
+ private BluetoothMapService mService;
+
+ BluetoothMapServiceBinder(BluetoothMapService service) {
+ mService = service;
+ }
+
+ @Override
+ public synchronized void cleanup() {
+ mService = null;
+ }
+
+ @RequiresPermission(BLUETOOTH_CONNECT)
+ private BluetoothMapService getService(AttributionSource source) {
+ BluetoothMapService service = mService;
+
+ if (Utils.isInstrumentationTestMode()) {
+ return service;
+ }
+
+ if (!Utils.checkServiceAvailable(service, TAG)
+ || !Utils.checkCallerIsSystemOrActiveOrManagedUser(service, TAG)
+ || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
+ return null;
+ }
+ return service;
+ }
+
+ @Override
+ public int getState(AttributionSource source) {
+ Log.v(TAG, "getState()");
+ try {
+ BluetoothMapService service = getService(source);
+ if (service == null) {
+ return BluetoothMap.STATE_DISCONNECTED;
+ }
+ return service.getState();
+ } catch (RuntimeException e) {
+ ContentProfileErrorReportUtils.report(
+ BluetoothProfile.MAP,
+ BluetoothProtoEnums.BLUETOOTH_MAP_SERVICE,
+ BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION,
+ 16);
+ throw e;
+ }
+ }
+
+ @Override
+ public BluetoothDevice getClient(AttributionSource source) {
+ Log.v(TAG, "getClient()");
+ try {
+ BluetoothMapService service = getService(source);
+ if (service == null) {
+ Log.v(TAG, "getClient() - no service - returning " + null);
+ return null;
+ }
+ BluetoothDevice client = service.getRemoteDevice();
+ Log.v(TAG, "getClient() - returning " + client);
+ return client;
+ } catch (RuntimeException e) {
+ ContentProfileErrorReportUtils.report(
+ BluetoothProfile.MAP,
+ BluetoothProtoEnums.BLUETOOTH_MAP_SERVICE,
+ BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION,
+ 17);
+ throw e;
+ }
+ }
+
+ @Override
+ public boolean isConnected(BluetoothDevice device, AttributionSource source) {
+ Log.v(TAG, "isConnected()");
+ try {
+ BluetoothMapService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+ return service.getConnectionState(device) == STATE_CONNECTED;
+ } catch (RuntimeException e) {
+ ContentProfileErrorReportUtils.report(
+ BluetoothProfile.MAP,
+ BluetoothProtoEnums.BLUETOOTH_MAP_SERVICE,
+ BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION,
+ 18);
+ throw e;
+ }
+ }
+
+ @Override
+ public boolean disconnect(BluetoothDevice device, AttributionSource source) {
+ Log.v(TAG, "disconnect()");
+ try {
+ BluetoothMapService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+ service.disconnect(device);
+ return true;
+ } catch (RuntimeException e) {
+ ContentProfileErrorReportUtils.report(
+ BluetoothProfile.MAP,
+ BluetoothProtoEnums.BLUETOOTH_MAP_SERVICE,
+ BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION,
+ 19);
+ throw e;
+ }
+ }
+
+ @Override
+ public List<BluetoothDevice> getConnectedDevices(AttributionSource source) {
+ Log.v(TAG, "getConnectedDevices()");
+ try {
+ BluetoothMapService service = getService(source);
+ if (service == null) {
+ return Collections.emptyList();
+ }
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.getConnectedDevices();
+ } catch (RuntimeException e) {
+ ContentProfileErrorReportUtils.report(
+ BluetoothProfile.MAP,
+ BluetoothProtoEnums.BLUETOOTH_MAP_SERVICE,
+ BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION,
+ 20);
+ throw e;
+ }
+ }
+
+ @Override
+ public List<BluetoothDevice> getDevicesMatchingConnectionStates(
+ int[] states, AttributionSource source) {
+ Log.v(TAG, "getDevicesMatchingConnectionStates()");
+ try {
+ BluetoothMapService service = getService(source);
+ if (service == null) {
+ return Collections.emptyList();
+ }
+ return service.getDevicesMatchingConnectionStates(states);
+ } catch (RuntimeException e) {
+ ContentProfileErrorReportUtils.report(
+ BluetoothProfile.MAP,
+ BluetoothProtoEnums.BLUETOOTH_MAP_SERVICE,
+ BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION,
+ 21);
+ throw e;
+ }
+ }
+
+ @Override
+ public int getConnectionState(BluetoothDevice device, AttributionSource source) {
+ Log.v(TAG, "getConnectionState()");
+ try {
+ BluetoothMapService service = getService(source);
+ if (service == null) {
+ return STATE_DISCONNECTED;
+ }
+ return service.getConnectionState(device);
+ } catch (RuntimeException e) {
+ ContentProfileErrorReportUtils.report(
+ BluetoothProfile.MAP,
+ BluetoothProtoEnums.BLUETOOTH_MAP_SERVICE,
+ BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION,
+ 22);
+ throw e;
+ }
+ }
+
+ @Override
+ public boolean setConnectionPolicy(
+ BluetoothDevice device, int connectionPolicy, AttributionSource source) {
+ try {
+ BluetoothMapService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+ return service.setConnectionPolicy(device, connectionPolicy);
+ } catch (RuntimeException e) {
+ ContentProfileErrorReportUtils.report(
+ BluetoothProfile.MAP,
+ BluetoothProtoEnums.BLUETOOTH_MAP_SERVICE,
+ BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION,
+ 23);
+ throw e;
+ }
+ }
+
+ @Override
+ public int getConnectionPolicy(BluetoothDevice device, AttributionSource source) {
+ try {
+ BluetoothMapService service = getService(source);
+ if (service == null) {
+ return CONNECTION_POLICY_UNKNOWN;
+ }
+ return service.getConnectionPolicy(device);
+ } catch (RuntimeException e) {
+ ContentProfileErrorReportUtils.report(
+ BluetoothProfile.MAP,
+ BluetoothProtoEnums.BLUETOOTH_MAP_SERVICE,
+ BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION,
+ 24);
+ throw e;
+ }
+ }
+}
diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapSmsPdu.java b/android/app/src/com/android/bluetooth/map/BluetoothMapSmsPdu.java
index 30cfebd1fe..d887860f56 100644
--- a/android/app/src/com/android/bluetooth/map/BluetoothMapSmsPdu.java
+++ b/android/app/src/com/android/bluetooth/map/BluetoothMapSmsPdu.java
@@ -39,6 +39,7 @@ import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
+import java.util.Locale;
import java.util.Random;
// Next tag value for ContentProfileErrorReportUtils.report(): 10
@@ -382,7 +383,7 @@ public class BluetoothMapSmsPdu {
@SuppressWarnings("JavaUtilDate") // TODO: b/365629730 -- prefer Instant or LocalDate
private static void gsmWriteDate(ByteArrayOutputStream header, long time) {
- SimpleDateFormat format = new SimpleDateFormat("yyMMddHHmmss");
+ SimpleDateFormat format = new SimpleDateFormat("yyMMddHHmmss", Locale.ROOT);
Date date = new Date(time);
String timeStr = format.format(date); // Format to YYMMDDTHHMMSS UTC time
Log.v(TAG, "Generated time string: " + timeStr);
@@ -400,11 +401,11 @@ public class BluetoothMapSmsPdu {
/ (15 * 60 * 1000); /* offset in quarters of an hour */
String offsetString;
if (offset < 0) {
- offsetString = String.format("%1$02d", -(offset));
+ offsetString = String.format(Locale.ROOT, "%1$02d", -(offset));
char[] offsetChars = offsetString.toCharArray();
header.write((offsetChars[1] - 0x30) << 4 | 0x40 | (offsetChars[0] - 0x30));
} else {
- offsetString = String.format("%1$02d", offset);
+ offsetString = String.format(Locale.ROOT, "%1$02d", offset);
char[] offsetChars = offsetString.toCharArray();
header.write((offsetChars[1] - 0x30) << 4 | (offsetChars[0] - 0x30));
}
diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapUtils.java b/android/app/src/com/android/bluetooth/map/BluetoothMapUtils.java
index d57db6a375..e92086ec5d 100644
--- a/android/app/src/com/android/bluetooth/map/BluetoothMapUtils.java
+++ b/android/app/src/com/android/bluetooth/map/BluetoothMapUtils.java
@@ -736,8 +736,8 @@ public class BluetoothMapUtils {
static String getDateTimeString(long timestamp) {
SimpleDateFormat format =
(mPeerSupportUtcTimeStamp)
- ? new SimpleDateFormat("yyyyMMdd'T'HHmmssZ")
- : new SimpleDateFormat("yyyyMMdd'T'HHmmss");
+ ? new SimpleDateFormat("yyyyMMdd'T'HHmmssZ", Locale.ROOT)
+ : new SimpleDateFormat("yyyyMMdd'T'HHmmss", Locale.ROOT);
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(timestamp);
Log.v(
diff --git a/android/app/src/com/android/bluetooth/mapclient/MapClientService.java b/android/app/src/com/android/bluetooth/mapclient/MapClientService.java
index 5e2be59b11..fdecfddf15 100644
--- a/android/app/src/com/android/bluetooth/mapclient/MapClientService.java
+++ b/android/app/src/com/android/bluetooth/mapclient/MapClientService.java
@@ -16,11 +16,8 @@
package com.android.bluetooth.mapclient;
-import static android.Manifest.permission.BLUETOOTH_CONNECT;
-import static android.Manifest.permission.BLUETOOTH_PRIVILEGED;
import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_ALLOWED;
import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
-import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_UNKNOWN;
import static android.bluetooth.BluetoothProfile.STATE_CONNECTED;
import static android.bluetooth.BluetoothProfile.STATE_CONNECTING;
import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTED;
@@ -28,16 +25,12 @@ import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTED;
import static java.util.Objects.requireNonNull;
import static java.util.Objects.requireNonNullElseGet;
-import android.Manifest;
-import android.annotation.RequiresPermission;
import android.app.PendingIntent;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothUuid;
-import android.bluetooth.IBluetoothMapClient;
import android.bluetooth.SdpMasRecord;
-import android.content.AttributionSource;
import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
@@ -46,7 +39,6 @@ import android.os.Parcelable;
import android.sysprop.BluetoothProperties;
import android.util.Log;
-import com.android.bluetooth.Utils;
import com.android.bluetooth.btservice.AdapterService;
import com.android.bluetooth.btservice.ProfileService;
import com.android.bluetooth.btservice.storage.DatabaseManager;
@@ -54,7 +46,6 @@ import com.android.internal.annotations.VisibleForTesting;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -307,7 +298,7 @@ public class MapClientService extends ProfileService {
@Override
public IProfileServiceBinder initBinder() {
- return new Binder(this);
+ return new MapClientServiceBinder(this);
}
@Override
@@ -408,172 +399,6 @@ public class MapClientService extends ProfileService {
}
}
- // Binder object: Must be static class or memory leak may occur
-
- /**
- * This class implements the IClient interface - or actually it validates the preconditions for
- * calling the actual functionality in the MapClientService, and calls it.
- */
- @VisibleForTesting
- static class Binder extends IBluetoothMapClient.Stub implements IProfileServiceBinder {
- private MapClientService mService;
-
- Binder(MapClientService service) {
- mService = service;
- }
-
- @Override
- public void cleanup() {
- mService = null;
- }
-
- @RequiresPermission(BLUETOOTH_CONNECT)
- private MapClientService getService(AttributionSource source) {
- // Cache mService because it can change while getService is called
- MapClientService service = mService;
-
- if (Utils.isInstrumentationTestMode()) {
- return service;
- }
-
- if (!Utils.checkServiceAvailable(service, TAG)
- || !(getCallingUserHandle().isSystem()
- || Utils.checkCallerIsSystemOrActiveOrManagedUser(service, TAG))
- || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
- return null;
- }
- return service;
- }
-
- @RequiresPermission(allOf = {BLUETOOTH_CONNECT, BLUETOOTH_PRIVILEGED})
- private MapClientService getServiceAndEnforcePrivileged(AttributionSource source) {
- // Cache mService because it can change while getService is called
- MapClientService service = mService;
-
- if (Utils.isInstrumentationTestMode()) {
- return service;
- }
-
- if (!Utils.checkServiceAvailable(service, TAG)
- || !(getCallingUserHandle().isSystem()
- || Utils.checkCallerIsSystemOrActiveOrManagedUser(service, TAG))
- || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
- return null;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- return service;
- }
-
- @Override
- public boolean connect(BluetoothDevice device, AttributionSource source) {
- Log.v(TAG, "connect()");
-
- MapClientService service = getServiceAndEnforcePrivileged(source);
- if (service == null) {
- return false;
- }
-
- return service.connect(device);
- }
-
- @Override
- public boolean disconnect(BluetoothDevice device, AttributionSource source) {
- Log.v(TAG, "disconnect()");
-
- MapClientService service = getServiceAndEnforcePrivileged(source);
- if (service == null) {
- return false;
- }
-
- return service.disconnect(device);
- }
-
- @Override
- public List<BluetoothDevice> getConnectedDevices(AttributionSource source) {
- Log.v(TAG, "getConnectedDevices()");
-
- MapClientService service = getServiceAndEnforcePrivileged(source);
- if (service == null) {
- return Collections.emptyList();
- }
-
- return service.getConnectedDevices();
- }
-
- @Override
- public List<BluetoothDevice> getDevicesMatchingConnectionStates(
- int[] states, AttributionSource source) {
- Log.v(TAG, "getDevicesMatchingConnectionStates()");
-
- MapClientService service = getServiceAndEnforcePrivileged(source);
- if (service == null) {
- return Collections.emptyList();
- }
- return service.getDevicesMatchingConnectionStates(states);
- }
-
- @Override
- public int getConnectionState(BluetoothDevice device, AttributionSource source) {
- Log.v(TAG, "getConnectionState()");
-
- MapClientService service = getServiceAndEnforcePrivileged(source);
- if (service == null) {
- return STATE_DISCONNECTED;
- }
-
- return service.getConnectionState(device);
- }
-
- @Override
- public boolean setConnectionPolicy(
- BluetoothDevice device, int connectionPolicy, AttributionSource source) {
- Log.v(TAG, "setConnectionPolicy()");
-
- MapClientService service = getServiceAndEnforcePrivileged(source);
- if (service == null) {
- return false;
- }
-
- return service.setConnectionPolicy(device, connectionPolicy);
- }
-
- @Override
- public int getConnectionPolicy(BluetoothDevice device, AttributionSource source) {
- Log.v(TAG, "getConnectionPolicy()");
-
- MapClientService service = getServiceAndEnforcePrivileged(source);
- if (service == null) {
- return CONNECTION_POLICY_UNKNOWN;
- }
-
- return service.getConnectionPolicy(device);
- }
-
- @Override
- public boolean sendMessage(
- BluetoothDevice device,
- Uri[] contacts,
- String message,
- PendingIntent sentIntent,
- PendingIntent deliveredIntent,
- AttributionSource source) {
- Log.v(TAG, "sendMessage()");
-
- MapClientService service = getService(source);
- if (service == null) {
- return false;
- }
-
- Log.d(TAG, "Checking Permission of sendMessage");
- mService.enforceCallingOrSelfPermission(
- Manifest.permission.SEND_SMS, "Need SEND_SMS permission");
-
- return service.sendMessage(device, contacts, message, sentIntent, deliveredIntent);
- }
- }
-
public void aclDisconnected(BluetoothDevice device, int transport) {
mHandler.post(() -> handleAclDisconnected(device, transport));
}
diff --git a/android/app/src/com/android/bluetooth/mapclient/MapClientServiceBinder.java b/android/app/src/com/android/bluetooth/mapclient/MapClientServiceBinder.java
new file mode 100644
index 0000000000..d6be8975e8
--- /dev/null
+++ b/android/app/src/com/android/bluetooth/mapclient/MapClientServiceBinder.java
@@ -0,0 +1,193 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.bluetooth.mapclient;
+
+import static android.Manifest.permission.BLUETOOTH_CONNECT;
+import static android.Manifest.permission.BLUETOOTH_PRIVILEGED;
+import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_UNKNOWN;
+import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTED;
+
+import android.Manifest;
+import android.annotation.RequiresPermission;
+import android.app.PendingIntent;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.IBluetoothMapClient;
+import android.content.AttributionSource;
+import android.net.Uri;
+import android.util.Log;
+
+import com.android.bluetooth.Utils;
+import com.android.bluetooth.btservice.ProfileService.IProfileServiceBinder;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * This class implements the IClient interface - or actually it validates the preconditions for
+ * calling the actual functionality in the MapClientService, and calls it.
+ */
+class MapClientServiceBinder extends IBluetoothMapClient.Stub implements IProfileServiceBinder {
+ private static final String TAG = MapClientServiceBinder.class.getSimpleName();
+
+ private MapClientService mService;
+
+ MapClientServiceBinder(MapClientService service) {
+ mService = service;
+ }
+
+ @Override
+ public void cleanup() {
+ mService = null;
+ }
+
+ @RequiresPermission(BLUETOOTH_CONNECT)
+ private MapClientService getService(AttributionSource source) {
+ MapClientService service = mService;
+
+ if (Utils.isInstrumentationTestMode()) {
+ return service;
+ }
+
+ if (!Utils.checkServiceAvailable(service, TAG)
+ || !(getCallingUserHandle().isSystem()
+ || Utils.checkCallerIsSystemOrActiveOrManagedUser(service, TAG))
+ || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
+ return null;
+ }
+ return service;
+ }
+
+ @RequiresPermission(allOf = {BLUETOOTH_CONNECT, BLUETOOTH_PRIVILEGED})
+ private MapClientService getServiceAndEnforcePrivileged(AttributionSource source) {
+ MapClientService service = mService;
+
+ if (Utils.isInstrumentationTestMode()) {
+ return service;
+ }
+
+ if (!Utils.checkServiceAvailable(service, TAG)
+ || !(getCallingUserHandle().isSystem()
+ || Utils.checkCallerIsSystemOrActiveOrManagedUser(service, TAG))
+ || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
+ return null;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service;
+ }
+
+ @Override
+ public boolean connect(BluetoothDevice device, AttributionSource source) {
+ Log.v(TAG, "connect()");
+
+ MapClientService service = getServiceAndEnforcePrivileged(source);
+ if (service == null) {
+ return false;
+ }
+ return service.connect(device);
+ }
+
+ @Override
+ public boolean disconnect(BluetoothDevice device, AttributionSource source) {
+ Log.v(TAG, "disconnect()");
+
+ MapClientService service = getServiceAndEnforcePrivileged(source);
+ if (service == null) {
+ return false;
+ }
+ return service.disconnect(device);
+ }
+
+ @Override
+ public List<BluetoothDevice> getConnectedDevices(AttributionSource source) {
+ Log.v(TAG, "getConnectedDevices()");
+
+ MapClientService service = getServiceAndEnforcePrivileged(source);
+ if (service == null) {
+ return Collections.emptyList();
+ }
+ return service.getConnectedDevices();
+ }
+
+ @Override
+ public List<BluetoothDevice> getDevicesMatchingConnectionStates(
+ int[] states, AttributionSource source) {
+ Log.v(TAG, "getDevicesMatchingConnectionStates()");
+
+ MapClientService service = getServiceAndEnforcePrivileged(source);
+ if (service == null) {
+ return Collections.emptyList();
+ }
+ return service.getDevicesMatchingConnectionStates(states);
+ }
+
+ @Override
+ public int getConnectionState(BluetoothDevice device, AttributionSource source) {
+ Log.v(TAG, "getConnectionState()");
+
+ MapClientService service = getServiceAndEnforcePrivileged(source);
+ if (service == null) {
+ return STATE_DISCONNECTED;
+ }
+ return service.getConnectionState(device);
+ }
+
+ @Override
+ public boolean setConnectionPolicy(
+ BluetoothDevice device, int connectionPolicy, AttributionSource source) {
+ Log.v(TAG, "setConnectionPolicy()");
+
+ MapClientService service = getServiceAndEnforcePrivileged(source);
+ if (service == null) {
+ return false;
+ }
+ return service.setConnectionPolicy(device, connectionPolicy);
+ }
+
+ @Override
+ public int getConnectionPolicy(BluetoothDevice device, AttributionSource source) {
+ Log.v(TAG, "getConnectionPolicy()");
+
+ MapClientService service = getServiceAndEnforcePrivileged(source);
+ if (service == null) {
+ return CONNECTION_POLICY_UNKNOWN;
+ }
+ return service.getConnectionPolicy(device);
+ }
+
+ @Override
+ public boolean sendMessage(
+ BluetoothDevice device,
+ Uri[] contacts,
+ String message,
+ PendingIntent sentIntent,
+ PendingIntent deliveredIntent,
+ AttributionSource source) {
+ Log.v(TAG, "sendMessage()");
+
+ MapClientService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+
+ Log.d(TAG, "Checking Permission of sendMessage");
+ mService.enforceCallingOrSelfPermission(
+ Manifest.permission.SEND_SMS, "Need SEND_SMS permission");
+
+ return service.sendMessage(device, contacts, message, sentIntent, deliveredIntent);
+ }
+}
diff --git a/android/app/src/com/android/bluetooth/mapclient/MceStateMachine.java b/android/app/src/com/android/bluetooth/mapclient/MceStateMachine.java
index 457e87c69f..c532af9b99 100644
--- a/android/app/src/com/android/bluetooth/mapclient/MceStateMachine.java
+++ b/android/app/src/com/android/bluetooth/mapclient/MceStateMachine.java
@@ -65,7 +65,6 @@ import android.telecom.PhoneAccount;
import android.telephony.SmsManager;
import android.util.Log;
-import com.android.bluetooth.BluetoothMetricsProto;
import com.android.bluetooth.Utils;
import com.android.bluetooth.btservice.AdapterService;
import com.android.bluetooth.btservice.MetricsLogger;
@@ -310,9 +309,6 @@ class MceStateMachine extends StateMachine {
+ prevState
+ ", new="
+ state);
- if (prevState != state && state == STATE_CONNECTED) {
- MetricsLogger.logProfileConnectionEvent(BluetoothMetricsProto.ProfileId.MAP_CLIENT);
- }
setState(state);
mAdapterService.updateProfileConnectionAdapterProperties(
diff --git a/android/app/src/com/android/bluetooth/mcp/GattOpContext.java b/android/app/src/com/android/bluetooth/mcp/GattOpContext.java
new file mode 100644
index 0000000000..fbd8442d58
--- /dev/null
+++ b/android/app/src/com/android/bluetooth/mcp/GattOpContext.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.bluetooth.mcp;
+
+import android.bluetooth.BluetoothGattCharacteristic;
+import android.bluetooth.BluetoothGattDescriptor;
+
+import com.google.protobuf.ByteString;
+
+public record GattOpContext(
+ Operation operation,
+ int requestId,
+ BluetoothGattCharacteristic characteristic,
+ BluetoothGattDescriptor descriptor,
+ boolean preparedWrite,
+ boolean responseNeeded,
+ int offset,
+ ByteString value) {
+ public enum Operation {
+ READ_CHARACTERISTIC,
+ WRITE_CHARACTERISTIC,
+ READ_DESCRIPTOR,
+ WRITE_DESCRIPTOR,
+ }
+
+ public GattOpContext(
+ Operation operation,
+ int requestId,
+ BluetoothGattCharacteristic characteristic,
+ BluetoothGattDescriptor descriptor,
+ int offset) {
+ this(operation, requestId, characteristic, descriptor, false, false, offset, null);
+ }
+}
diff --git a/android/app/src/com/android/bluetooth/mcp/McpService.java b/android/app/src/com/android/bluetooth/mcp/McpService.java
index c0ba4f12bb..6f08be0061 100644
--- a/android/app/src/com/android/bluetooth/mcp/McpService.java
+++ b/android/app/src/com/android/bluetooth/mcp/McpService.java
@@ -17,12 +17,9 @@
package com.android.bluetooth.mcp;
-import static android.Manifest.permission.BLUETOOTH_PRIVILEGED;
import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
import android.bluetooth.BluetoothDevice;
-import android.bluetooth.IBluetoothMcpServiceManager;
-import android.content.AttributionSource;
import android.content.Context;
import android.os.ParcelUuid;
import android.sysprop.BluetoothProperties;
@@ -88,7 +85,7 @@ public class McpService extends ProfileService {
@Override
protected IProfileServiceBinder initBinder() {
- return new BluetoothMcpServiceBinder(this);
+ return new McpServiceBinder(this);
}
@Override
@@ -198,41 +195,4 @@ public class McpService extends ProfileService {
int ccid, BluetoothDevice device, ParcelUuid charUuid, boolean doNotify) {
mGmcs.setNotificationSubscription(ccid, device, charUuid, doNotify);
}
-
- /** Binder object: must be a static class or memory leak may occur */
- static class BluetoothMcpServiceBinder extends IBluetoothMcpServiceManager.Stub
- implements IProfileServiceBinder {
- private McpService mService;
-
- BluetoothMcpServiceBinder(McpService svc) {
- mService = svc;
- }
-
- private McpService getService() {
- if (mService != null && mService.isAvailable()) {
- return mService;
- }
- Log.e(TAG, "getService() - Service requested, but not available!");
- return null;
- }
-
- @Override
- public void setDeviceAuthorized(
- BluetoothDevice device, boolean isAuthorized, AttributionSource source) {
- McpService service = getService();
- if (service == null) {
- return;
- }
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- service.setDeviceAuthorized(device, isAuthorized);
- }
-
- @Override
- public void cleanup() {
- if (mService != null) {
- mService.cleanup();
- }
- mService = null;
- }
- }
}
diff --git a/android/app/src/com/android/bluetooth/mcp/McpServiceBinder.java b/android/app/src/com/android/bluetooth/mcp/McpServiceBinder.java
new file mode 100644
index 0000000000..b22e87cadf
--- /dev/null
+++ b/android/app/src/com/android/bluetooth/mcp/McpServiceBinder.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.bluetooth.mcp;
+
+import static android.Manifest.permission.BLUETOOTH_PRIVILEGED;
+
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.IBluetoothMcpServiceManager;
+import android.content.AttributionSource;
+import android.util.Log;
+
+import com.android.bluetooth.btservice.ProfileService.IProfileServiceBinder;
+
+class McpServiceBinder extends IBluetoothMcpServiceManager.Stub implements IProfileServiceBinder {
+ private static final String TAG = McpServiceBinder.class.getSimpleName();
+
+ private McpService mService;
+
+ McpServiceBinder(McpService svc) {
+ mService = svc;
+ }
+
+ private McpService getService() {
+ if (mService != null && mService.isAvailable()) {
+ return mService;
+ }
+ Log.e(TAG, "getService() - Service requested, but not available!");
+ return null;
+ }
+
+ @Override
+ public void setDeviceAuthorized(
+ BluetoothDevice device, boolean isAuthorized, AttributionSource source) {
+ McpService service = getService();
+ if (service == null) {
+ return;
+ }
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ service.setDeviceAuthorized(device, isAuthorized);
+ }
+
+ @Override
+ public void cleanup() {
+ if (mService != null) {
+ mService.cleanup();
+ }
+ mService = null;
+ }
+}
diff --git a/android/app/src/com/android/bluetooth/mcp/MediaControlGattService.java b/android/app/src/com/android/bluetooth/mcp/MediaControlGattService.java
index 80221a484a..26b5c2eb68 100644
--- a/android/app/src/com/android/bluetooth/mcp/MediaControlGattService.java
+++ b/android/app/src/com/android/bluetooth/mcp/MediaControlGattService.java
@@ -212,32 +212,6 @@ public class MediaControlGattService implements MediaControlGattServiceInterface
}
}
- private record GattOpContext(
- Operation operation,
- int requestId,
- BluetoothGattCharacteristic characteristic,
- BluetoothGattDescriptor descriptor,
- boolean preparedWrite,
- boolean responseNeeded,
- int offset,
- ByteString value) {
- public enum Operation {
- READ_CHARACTERISTIC,
- WRITE_CHARACTERISTIC,
- READ_DESCRIPTOR,
- WRITE_DESCRIPTOR,
- }
-
- GattOpContext(
- Operation operation,
- int requestId,
- BluetoothGattCharacteristic characteristic,
- BluetoothGattDescriptor descriptor,
- int offset) {
- this(operation, requestId, characteristic, descriptor, false, false, offset, null);
- }
- }
-
private final Map<UUID, CharacteristicWriteHandler> mCharWriteCallback =
Map.of(
UUID_TRACK_POSITION,
@@ -430,7 +404,7 @@ public class MediaControlGattService implements MediaControlGattServiceInterface
}
private void onUnauthorizedCharRead(BluetoothDevice device, GattOpContext op) {
- UUID charUuid = op.characteristic.getUuid();
+ UUID charUuid = op.characteristic().getUuid();
byte[] buffer = null;
if (charUuid.equals(UUID_PLAYER_NAME)) {
@@ -520,89 +494,89 @@ public class MediaControlGattService implements MediaControlGattServiceInterface
} else if (charUuid.equals(UUID_CONTENT_CONTROL_ID)) {
// It is ok, to send the real value for CCID
- if (op.characteristic.getValue() != null) {
+ if (op.characteristic().getValue() != null) {
buffer =
Arrays.copyOfRange(
- op.characteristic.getValue(),
- op.offset,
- op.characteristic.getValue().length);
+ op.characteristic().getValue(),
+ op.offset(),
+ op.characteristic().getValue().length);
}
}
if (buffer != null) {
mBluetoothGattServer.sendResponse(
- device, op.requestId, BluetoothGatt.GATT_SUCCESS, op.offset, buffer);
+ device, op.requestId(), BluetoothGatt.GATT_SUCCESS, op.offset(), buffer);
} else {
mEventLogger.loge(
TAG, "Missing characteristic value for char: " + mcsUuidToString(charUuid));
mBluetoothGattServer.sendResponse(
device,
- op.requestId,
+ op.requestId(),
BluetoothGatt.GATT_INVALID_ATTRIBUTE_LENGTH,
- op.offset,
+ op.offset(),
buffer);
}
}
private void onUnauthorizedGattOperation(BluetoothDevice device, GattOpContext op) {
UUID charUuid =
- (op.characteristic != null
- ? op.characteristic.getUuid()
- : (op.descriptor != null
- ? op.descriptor.getCharacteristic().getUuid()
+ (op.characteristic() != null
+ ? op.characteristic().getUuid()
+ : (op.descriptor() != null
+ ? op.descriptor().getCharacteristic().getUuid()
: null));
mEventLogger.logw(
TAG,
"onUnauthorizedGattOperation: device= "
+ device
+ ", opcode= "
- + op.descriptor
+ + op.descriptor()
+ ", characteristic= "
+ (charUuid != null ? mcsUuidToString(charUuid) : "UNKNOWN"));
- switch (op.operation) {
+ switch (op.operation()) {
/* Allow not yet authorized devices to subscribe for notifications */
case READ_DESCRIPTOR:
- if (op.offset > 1) {
+ if (op.offset() > 1) {
mBluetoothGattServer.sendResponse(
device,
- op.requestId,
+ op.requestId(),
BluetoothGatt.GATT_INVALID_OFFSET,
- op.offset,
+ op.offset(),
null);
return;
}
- byte[] value = getCccBytes(device, op.descriptor.getCharacteristic().getUuid());
+ byte[] value = getCccBytes(device, op.descriptor().getCharacteristic().getUuid());
if (value == null) {
mBluetoothGattServer.sendResponse(
- device, op.requestId, BluetoothGatt.GATT_FAILURE, op.offset, null);
+ device, op.requestId(), BluetoothGatt.GATT_FAILURE, op.offset(), null);
return;
}
- value = Arrays.copyOfRange(value, op.offset, value.length);
+ value = Arrays.copyOfRange(value, op.offset(), value.length);
mBluetoothGattServer.sendResponse(
- device, op.requestId, BluetoothGatt.GATT_SUCCESS, op.offset, value);
+ device, op.requestId(), BluetoothGatt.GATT_SUCCESS, op.offset(), value);
return;
case WRITE_DESCRIPTOR:
int status = BluetoothGatt.GATT_SUCCESS;
- if (op.preparedWrite) {
+ if (op.preparedWrite()) {
status = BluetoothGatt.GATT_FAILURE;
- } else if (op.offset > 0) {
+ } else if (op.offset() > 0) {
status = BluetoothGatt.GATT_INVALID_OFFSET;
} else {
status = BluetoothGatt.GATT_SUCCESS;
setCcc(
device,
- op.descriptor.getCharacteristic().getUuid(),
- op.offset,
- op.value.toByteArray(),
+ op.descriptor().getCharacteristic().getUuid(),
+ op.offset(),
+ op.value().toByteArray(),
true);
}
- if (op.responseNeeded) {
+ if (op.responseNeeded()) {
mBluetoothGattServer.sendResponse(
- device, op.requestId, status, op.offset, op.value.toByteArray());
+ device, op.requestId(), status, op.offset(), op.value().toByteArray());
}
return;
case READ_CHARACTERISTIC:
@@ -632,26 +606,26 @@ public class MediaControlGattService implements MediaControlGattServiceInterface
private void onAuthorizedGattOperation(BluetoothDevice device, GattOpContext op) {
UUID charUuid =
- (op.characteristic != null
- ? op.characteristic.getUuid()
- : (op.descriptor != null
- ? op.descriptor.getCharacteristic().getUuid()
+ (op.characteristic() != null
+ ? op.characteristic().getUuid()
+ : (op.descriptor() != null
+ ? op.descriptor().getCharacteristic().getUuid()
: null));
mEventLogger.logd(
TAG,
"onAuthorizedGattOperation: device= "
+ device
+ ", opcode= "
- + op.operation
+ + op.operation()
+ ", characteristic= "
+ (charUuid != null ? mcsUuidToString(charUuid) : "UNKNOWN"));
int status = BluetoothGatt.GATT_SUCCESS;
- switch (op.operation) {
+ switch (op.operation()) {
case READ_CHARACTERISTIC:
// Always ask for the latest position
- if (op.characteristic
+ if (op.characteristic()
.getUuid()
.equals(mCharacteristics.get(CharId.TRACK_POSITION).getUuid())) {
long positionMs = mCallbacks.onGetCurrentTrackPosition();
@@ -666,110 +640,111 @@ public class MediaControlGattService implements MediaControlGattServiceInterface
mBluetoothGattServer.sendResponse(
device,
- op.requestId,
+ op.requestId(),
BluetoothGatt.GATT_SUCCESS,
- op.offset,
- Arrays.copyOfRange(bb.array(), op.offset, Integer.BYTES));
+ op.offset(),
+ Arrays.copyOfRange(bb.array(), op.offset(), Integer.BYTES));
return;
}
- byte[] readRespValue = op.characteristic.getValue();
+ byte[] readRespValue = op.characteristic().getValue();
if (readRespValue != null) {
- if (readRespValue.length >= op.offset) {
+ if (readRespValue.length >= op.offset()) {
status = BluetoothGatt.GATT_SUCCESS;
readRespValue =
- Arrays.copyOfRange(readRespValue, op.offset, readRespValue.length);
+ Arrays.copyOfRange(
+ readRespValue, op.offset(), readRespValue.length);
} else {
Log.e(
TAG,
- ("Wrong offset read for: " + op.characteristic.getUuid())
- + (": offset " + op.offset)
+ ("Wrong offset read for: " + op.characteristic().getUuid())
+ + (": offset " + op.offset())
+ (", total len: " + readRespValue.length));
status = BluetoothGatt.GATT_INVALID_OFFSET;
readRespValue = new byte[] {};
}
mBluetoothGattServer.sendResponse(
- device, op.requestId, status, op.offset, readRespValue);
+ device, op.requestId(), status, op.offset(), readRespValue);
} else {
Log.e(
TAG,
"Missing characteristic value for char: "
- + op.characteristic.getUuid());
+ + op.characteristic().getUuid());
mBluetoothGattServer.sendResponse(
device,
- op.requestId,
+ op.requestId(),
BluetoothGatt.GATT_INVALID_ATTRIBUTE_LENGTH,
- op.offset,
+ op.offset(),
new byte[] {});
}
break;
case WRITE_CHARACTERISTIC:
- if (op.preparedWrite) {
+ if (op.preparedWrite()) {
status = BluetoothGatt.GATT_FAILURE;
- } else if (op.offset > 0) {
+ } else if (op.offset() > 0) {
status = BluetoothGatt.GATT_INVALID_OFFSET;
} else {
CharacteristicWriteHandler handler =
- mCharWriteCallback.get(op.characteristic.getUuid());
+ mCharWriteCallback.get(op.characteristic().getUuid());
handler.onCharacteristicWriteRequest(
device,
- op.requestId,
- op.characteristic,
- op.preparedWrite,
- op.responseNeeded,
- op.offset,
- op.value.toByteArray());
+ op.requestId(),
+ op.characteristic(),
+ op.preparedWrite(),
+ op.responseNeeded(),
+ op.offset(),
+ op.value().toByteArray());
break;
}
- if (op.responseNeeded) {
+ if (op.responseNeeded()) {
mBluetoothGattServer.sendResponse(
- device, op.requestId, status, op.offset, op.value.toByteArray());
+ device, op.requestId(), status, op.offset(), op.value().toByteArray());
}
break;
case READ_DESCRIPTOR:
- if (op.offset > 1) {
+ if (op.offset() > 1) {
mBluetoothGattServer.sendResponse(
device,
- op.requestId,
+ op.requestId(),
BluetoothGatt.GATT_INVALID_OFFSET,
- op.offset,
+ op.offset(),
null);
break;
}
- byte[] value = getCccBytes(device, op.descriptor.getCharacteristic().getUuid());
+ byte[] value = getCccBytes(device, op.descriptor().getCharacteristic().getUuid());
if (value == null) {
mBluetoothGattServer.sendResponse(
- device, op.requestId, BluetoothGatt.GATT_FAILURE, op.offset, null);
+ device, op.requestId(), BluetoothGatt.GATT_FAILURE, op.offset(), null);
break;
}
- value = Arrays.copyOfRange(value, op.offset, value.length);
+ value = Arrays.copyOfRange(value, op.offset(), value.length);
mBluetoothGattServer.sendResponse(
- device, op.requestId, BluetoothGatt.GATT_SUCCESS, op.offset, value);
+ device, op.requestId(), BluetoothGatt.GATT_SUCCESS, op.offset(), value);
break;
case WRITE_DESCRIPTOR:
- if (op.preparedWrite) {
+ if (op.preparedWrite()) {
status = BluetoothGatt.GATT_FAILURE;
- } else if (op.offset > 0) {
+ } else if (op.offset() > 0) {
status = BluetoothGatt.GATT_INVALID_OFFSET;
} else {
status = BluetoothGatt.GATT_SUCCESS;
setCcc(
device,
- op.descriptor.getCharacteristic().getUuid(),
- op.offset,
- op.value.toByteArray(),
+ op.descriptor().getCharacteristic().getUuid(),
+ op.offset(),
+ op.value().toByteArray(),
true);
}
- if (op.responseNeeded) {
+ if (op.responseNeeded()) {
mBluetoothGattServer.sendResponse(
- device, op.requestId, status, op.offset, op.value.toByteArray());
+ device, op.requestId(), status, op.offset(), op.value().toByteArray());
}
break;
@@ -780,56 +755,56 @@ public class MediaControlGattService implements MediaControlGattServiceInterface
private void onRejectedAuthorizationGattOperation(BluetoothDevice device, GattOpContext op) {
UUID charUuid =
- (op.characteristic != null
- ? op.characteristic.getUuid()
- : (op.descriptor != null
- ? op.descriptor.getCharacteristic().getUuid()
+ (op.characteristic() != null
+ ? op.characteristic().getUuid()
+ : (op.descriptor() != null
+ ? op.descriptor().getCharacteristic().getUuid()
: null));
mEventLogger.logw(
TAG,
"onRejectedAuthorizationGattOperation: device= "
+ device
+ ", opcode= "
- + op.operation
+ + op.operation()
+ ", characteristic= "
+ (charUuid != null ? mcsUuidToString(charUuid) : "UNKNOWN"));
- switch (op.operation) {
+ switch (op.operation()) {
case READ_CHARACTERISTIC:
case READ_DESCRIPTOR:
mBluetoothGattServer.sendResponse(
device,
- op.requestId,
+ op.requestId(),
BluetoothGatt.GATT_INSUFFICIENT_AUTHORIZATION,
- op.offset,
+ op.offset(),
null);
break;
case WRITE_CHARACTERISTIC:
- if (op.responseNeeded) {
+ if (op.responseNeeded()) {
mBluetoothGattServer.sendResponse(
device,
- op.requestId,
+ op.requestId(),
BluetoothGatt.GATT_INSUFFICIENT_AUTHORIZATION,
- op.offset,
+ op.offset(),
null);
} else {
// In case of control point operations we can send an application error code
- if (op.characteristic.getUuid().equals(UUID_MEDIA_CONTROL_POINT)) {
+ if (op.characteristic().getUuid().equals(UUID_MEDIA_CONTROL_POINT)) {
setMediaControlRequestResult(
- new Request(op.value.toByteArray()[0], 0),
+ new Request(op.value().toByteArray()[0], 0),
Request.Results.COMMAND_CANNOT_BE_COMPLETED);
- } else if (op.characteristic.getUuid().equals(UUID_SEARCH_CONTROL_POINT)) {
+ } else if (op.characteristic().getUuid().equals(UUID_SEARCH_CONTROL_POINT)) {
setSearchRequestResult(null, SearchRequest.Results.FAILURE, 0);
}
}
break;
case WRITE_DESCRIPTOR:
- if (op.responseNeeded) {
+ if (op.responseNeeded()) {
mBluetoothGattServer.sendResponse(
device,
- op.requestId,
+ op.requestId(),
BluetoothGatt.GATT_INSUFFICIENT_AUTHORIZATION,
- op.offset,
+ op.offset(),
null);
}
break;
diff --git a/android/app/src/com/android/bluetooth/notification/NotificationHelperService.java b/android/app/src/com/android/bluetooth/notification/NotificationHelperService.java
index a9a7d9a408..e87bd90ae4 100644
--- a/android/app/src/com/android/bluetooth/notification/NotificationHelperService.java
+++ b/android/app/src/com/android/bluetooth/notification/NotificationHelperService.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 The Android Open Source Project
+ * Copyright (C) 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.
diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppLauncherActivity.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppLauncherActivity.java
index 048c134848..73cba4e954 100644
--- a/android/app/src/com/android/bluetooth/opp/BluetoothOppLauncherActivity.java
+++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppLauncherActivity.java
@@ -248,6 +248,12 @@ public class BluetoothOppLauncherActivity extends Activity {
permittedUris,
false /* isHandover */,
true /* fromExternal */);
+ if (Flags.sendOppDevicePickerExtraIntent()) {
+ BluetoothOppUtility
+ .grantPermissionToNearbyComponent(
+ BluetoothOppLauncherActivity.this,
+ uris);
+ }
// Done getting file info..Launch device picker
// and finish this activity
launchDevicePicker();
@@ -322,6 +328,11 @@ public class BluetoothOppLauncherActivity extends Activity {
in1.putExtra(BluetoothDevicePicker.EXTRA_LAUNCH_PACKAGE, getPackageName());
in1.putExtra(
BluetoothDevicePicker.EXTRA_LAUNCH_CLASS, BluetoothOppReceiver.class.getName());
+ if (Flags.sendOppDevicePickerExtraIntent()) {
+ in1.putExtra(
+ BluetoothDevicePicker.EXTRA_DEVICE_PICKER_ORIGINAL_SEND_INTENT,
+ getIntent());
+ }
Log.v(TAG, "Launching " + BluetoothDevicePicker.ACTION_LAUNCH);
startActivity(in1);
}
@@ -555,6 +566,10 @@ public class BluetoothOppLauncherActivity extends Activity {
void sendFileInfo(String mimeType, String uriString, boolean isHandover, boolean fromExternal) {
BluetoothOppManager manager = BluetoothOppManager.getInstance(getApplicationContext());
try {
+ if (Flags.sendOppDevicePickerExtraIntent()) {
+ BluetoothOppUtility.grantPermissionToNearbyComponent(
+ this, List.of(Uri.parse(uriString)));
+ }
manager.saveSendingFileInfo(mimeType, uriString, isHandover, fromExternal);
launchDevicePicker();
finish();
diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppObexClientSession.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppObexClientSession.java
index 6f365e7507..666ed9b2fc 100644
--- a/android/app/src/com/android/bluetooth/opp/BluetoothOppObexClientSession.java
+++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppObexClientSession.java
@@ -48,7 +48,6 @@ import android.os.SystemClock;
import android.util.Log;
import com.android.bluetooth.BluetoothMethodProxy;
-import com.android.bluetooth.BluetoothMetricsProto;
import com.android.bluetooth.BluetoothStatsLog;
import com.android.bluetooth.btservice.MetricsLogger;
import com.android.bluetooth.content_profiles.ContentProfileErrorReportUtils;
@@ -76,8 +75,6 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession {
private ClientThread mThread;
private volatile boolean mInterrupted;
- private int mNumFilesAttemptedToSend;
-
public BluetoothOppObexClientSession(Context context, ObexTransport transport) {
mContext = requireNonNull(context);
mTransport = requireNonNull(transport);
@@ -175,7 +172,6 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession {
connect(mNumShares);
}
- mNumFilesAttemptedToSend = 0;
while (!mInterrupted) {
if (!mWaitingForShare) {
doSend();
@@ -200,10 +196,6 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession {
mWakeLock.release();
}
- if (mNumFilesAttemptedToSend > 0) {
- // Log outgoing OPP transfer if more than one file is accepted by remote
- MetricsLogger.logProfileConnectionEvent(BluetoothMetricsProto.ProfileId.OPP);
- }
Message msg = Message.obtain(mCallbackHandler);
msg.what = BluetoothOppObexSession.MSG_SESSION_COMPLETE;
msg.obj = mInfo;
@@ -503,7 +495,6 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession {
updateValues.put(BluetoothShare.CURRENT_BYTES, position);
mContext.getContentResolver()
.update(contentUri, updateValues, null, null);
- mNumFilesAttemptedToSend++;
} else {
Log.i(TAG, "Remote reject, Response code is " + responseCode);
}
diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppObexServerSession.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppObexServerSession.java
index cc92f0cb03..e4d08c6fd9 100644
--- a/android/app/src/com/android/bluetooth/opp/BluetoothOppObexServerSession.java
+++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppObexServerSession.java
@@ -47,7 +47,6 @@ import android.util.Log;
import android.webkit.MimeTypeMap;
import com.android.bluetooth.BluetoothMethodProxy;
-import com.android.bluetooth.BluetoothMetricsProto;
import com.android.bluetooth.BluetoothObexTransport;
import com.android.bluetooth.BluetoothStatsLog;
import com.android.bluetooth.Utils;
@@ -82,7 +81,6 @@ public class BluetoothOppObexServerSession extends ServerRequestHandler
private long mTimestamp;
private boolean mInterrupted;
private int mLocalShareInfoId; // info id when we insert the record
- private int mNumFilesAttemptedToReceive;
@VisibleForTesting boolean mTimeoutMsgSent;
@VisibleForTesting public ServerSession mSession;
@VisibleForTesting BluetoothOppReceiveFileInfo mFileInfo;
@@ -362,7 +360,6 @@ public class BluetoothOppObexServerSession extends ServerRequestHandler
|| mAccepted == BluetoothShare.USER_CONFIRMATION_AUTO_CONFIRMED
|| mAccepted == BluetoothShare.USER_CONFIRMATION_HANDOVER_CONFIRMED) {
/* Confirm or auto-confirm */
- mNumFilesAttemptedToReceive++;
if (mFileInfo.mFileName == null) {
status = mFileInfo.mStatus;
@@ -649,17 +646,12 @@ public class BluetoothOppObexServerSession extends ServerRequestHandler
Utils.getTempBroadcastOptions().toBundle());
}
mTimestamp = System.currentTimeMillis();
- mNumFilesAttemptedToReceive = 0;
return ResponseCodes.OBEX_HTTP_OK;
}
@Override
public void onDisconnect(HeaderSet req, HeaderSet resp) {
Log.d(TAG, "onDisconnect");
- if (mNumFilesAttemptedToReceive > 0) {
- // Log incoming OPP transfer if more than one file is accepted by user
- MetricsLogger.logProfileConnectionEvent(BluetoothMetricsProto.ProfileId.OPP);
- }
resp.responseCode = ResponseCodes.OBEX_HTTP_OK;
}
diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppReceiveFileInfo.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppReceiveFileInfo.java
index 55004bbd1d..0ef16173e8 100644
--- a/android/app/src/com/android/bluetooth/opp/BluetoothOppReceiveFileInfo.java
+++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppReceiveFileInfo.java
@@ -51,6 +51,7 @@ import java.nio.charset.StandardCharsets;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
+import java.util.Locale;
/**
* This class stores information about a single receiving file. It will only be used for inbounds
@@ -164,7 +165,7 @@ public class BluetoothOppReceiveFileInfo {
Log.d(Constants.TAG, "File name is too long. Name is truncated as: " + filename);
}
- DateFormat dateFormat = new SimpleDateFormat("_hhmmss");
+ DateFormat dateFormat = new SimpleDateFormat("_hhmmss", Locale.ROOT);
String currentTime = dateFormat.format(Calendar.getInstance().getTime());
String fullFilename = filename + currentTime + extension;
diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppUtility.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppUtility.java
index d7b75bfde2..4e8892ab35 100644
--- a/android/app/src/com/android/bluetooth/opp/BluetoothOppUtility.java
+++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppUtility.java
@@ -38,6 +38,7 @@ import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothProtoEnums;
import android.content.ActivityNotFoundException;
+import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
@@ -50,6 +51,7 @@ import android.net.Uri;
import android.os.Environment;
import android.os.ParcelFileDescriptor;
import android.os.SystemProperties;
+import android.provider.Settings;
import android.util.EventLog;
import android.util.Log;
@@ -77,6 +79,9 @@ import java.util.concurrent.ConcurrentHashMap;
public class BluetoothOppUtility {
private static final String TAG = BluetoothOppUtility.class.getSimpleName();
+ // TODO(b/398120192): use API instead of a hardcode string.
+ private static final String NEARBY_SHARING_COMPONENT = "nearby_sharing_component";
+
/** Whether the device has the "nosdcard" characteristic, or null if not-yet-known. */
private static Boolean sNoSdCard = null;
@@ -572,4 +577,30 @@ public class BluetoothOppUtility {
NotificationManager nm = ctx.getSystemService(NotificationManager.class);
nm.cancel(BluetoothOppNotification.NOTIFICATION_ID_PROGRESS);
}
+
+ /** Grants uri read permission to nearby sharing component. */
+ static void grantPermissionToNearbyComponent(Context context, List<Uri> uris) {
+ String packageName = getNearbyComponentPackageName(context);
+ if (packageName == null) {
+ return;
+ }
+ for (Uri uri : uris) {
+ BluetoothMethodProxy.getInstance()
+ .grantUriPermission(
+ context, packageName, uri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
+ }
+ }
+
+ private static String getNearbyComponentPackageName(Context context) {
+ String componentString =
+ Settings.Secure.getString(context.getContentResolver(), NEARBY_SHARING_COMPONENT);
+ if (componentString == null) {
+ return null;
+ }
+ ComponentName componentName = ComponentName.unflattenFromString(componentString);
+ if (componentName == null) {
+ return null;
+ }
+ return componentName.getPackageName();
+ }
}
diff --git a/android/app/src/com/android/bluetooth/pan/PanNativeInterface.java b/android/app/src/com/android/bluetooth/pan/PanNativeInterface.java
index 76e91d8477..dc203821b2 100644
--- a/android/app/src/com/android/bluetooth/pan/PanNativeInterface.java
+++ b/android/app/src/com/android/bluetooth/pan/PanNativeInterface.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 The Android Open Source Project
+ * Copyright (C) 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.
diff --git a/android/app/src/com/android/bluetooth/pan/PanService.java b/android/app/src/com/android/bluetooth/pan/PanService.java
index 11788f9cf4..5c2dfdf2a7 100644
--- a/android/app/src/com/android/bluetooth/pan/PanService.java
+++ b/android/app/src/com/android/bluetooth/pan/PanService.java
@@ -17,8 +17,6 @@
package com.android.bluetooth.pan;
import static android.Manifest.permission.BLUETOOTH_CONNECT;
-import static android.Manifest.permission.BLUETOOTH_PRIVILEGED;
-import static android.Manifest.permission.TETHER_PRIVILEGED;
import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_ALLOWED;
import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
import static android.bluetooth.BluetoothProfile.STATE_CONNECTED;
@@ -30,15 +28,12 @@ import static android.bluetooth.BluetoothUtils.logRemoteException;
import static java.util.Objects.requireNonNull;
import static java.util.Objects.requireNonNullElseGet;
-import android.annotation.RequiresPermission;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothPan;
import android.bluetooth.BluetoothPan.LocalPanRole;
import android.bluetooth.BluetoothPan.RemotePanRole;
import android.bluetooth.BluetoothProfile;
-import android.bluetooth.IBluetoothPan;
import android.bluetooth.IBluetoothPanCallback;
-import android.content.AttributionSource;
import android.content.Intent;
import android.content.res.Resources.NotFoundException;
import android.net.TetheringInterface;
@@ -51,10 +46,8 @@ import android.os.UserManager;
import android.sysprop.BluetoothProperties;
import android.util.Log;
-import com.android.bluetooth.BluetoothMetricsProto;
import com.android.bluetooth.Utils;
import com.android.bluetooth.btservice.AdapterService;
-import com.android.bluetooth.btservice.MetricsLogger;
import com.android.bluetooth.btservice.ProfileService;
import com.android.bluetooth.btservice.storage.DatabaseManager;
import com.android.bluetooth.flags.Flags;
@@ -62,7 +55,6 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.modules.utils.HandlerExecutor;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -156,7 +148,7 @@ public class PanService extends ProfileService {
@Override
public IProfileServiceBinder initBinder() {
- return new BluetoothPanBinder(this);
+ return new PanServiceBinder(this);
}
public static synchronized PanService getPanService() {
@@ -278,137 +270,6 @@ public class PanService extends ProfileService {
}
}
- /** Handlers for incoming service calls */
- @VisibleForTesting
- static class BluetoothPanBinder extends IBluetoothPan.Stub implements IProfileServiceBinder {
- private PanService mService;
-
- BluetoothPanBinder(PanService svc) {
- mService = svc;
- }
-
- @Override
- public void cleanup() {
- mService = null;
- }
-
- @RequiresPermission(BLUETOOTH_CONNECT)
- private PanService getService(AttributionSource source) {
- if (Utils.isInstrumentationTestMode()) {
- return mService;
- }
- if (!Utils.checkServiceAvailable(mService, TAG)
- || !Utils.checkCallerIsSystemOrActiveOrManagedUser(mService, TAG)
- || !Utils.checkConnectPermissionForDataDelivery(mService, source, TAG)) {
- return null;
- }
- return mService;
- }
-
- @Override
- public boolean connect(BluetoothDevice device, AttributionSource source) {
- PanService service = getService(source);
- if (service == null) {
- return false;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- return service.connect(device);
- }
-
- @Override
- public boolean disconnect(BluetoothDevice device, AttributionSource source) {
- PanService service = getService(source);
- if (service == null) {
- return false;
- }
-
- return service.disconnect(device);
- }
-
- @Override
- public boolean setConnectionPolicy(
- BluetoothDevice device, int connectionPolicy, AttributionSource source) {
- PanService service = getService(source);
- if (service == null) {
- return false;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- return service.setConnectionPolicy(device, connectionPolicy);
- }
-
- @Override
- public int getConnectionState(BluetoothDevice device, AttributionSource source) {
- PanService service = getService(source);
- if (service == null) {
- return BluetoothPan.STATE_DISCONNECTED;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- return service.getConnectionState(device);
- }
-
- @Override
- public boolean isTetheringOn(AttributionSource source) {
- // TODO(BT) have a variable marking the on/off state
- PanService service = getService(source);
- if (service == null) {
- return false;
- }
-
- return service.isTetheringOn();
- }
-
- @Override
- public void setBluetoothTethering(
- IBluetoothPanCallback callback, int id, boolean value, AttributionSource source) {
- PanService service = getService(source);
- if (service == null) {
- return;
- }
-
- Log.d(
- TAG,
- "setBluetoothTethering:"
- + (" value=" + value)
- + (" pkgName= " + source.getPackageName())
- + (" mTetherOn= " + service.mTetherOn));
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- service.enforceCallingOrSelfPermission(TETHER_PRIVILEGED, null);
-
- service.setBluetoothTethering(callback, id, source.getUid(), value);
- }
-
- @Override
- public List<BluetoothDevice> getConnectedDevices(AttributionSource source) {
- PanService service = getService(source);
- if (service == null) {
- return Collections.emptyList();
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- return service.getConnectedDevices();
- }
-
- @Override
- public List<BluetoothDevice> getDevicesMatchingConnectionStates(
- int[] states, AttributionSource source) {
- PanService service = getService(source);
- if (service == null) {
- return Collections.emptyList();
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- return service.getDevicesMatchingConnectionStates(states);
- }
- }
-
public boolean connect(BluetoothDevice device) {
if (mUserManager.isGuestUser()) {
Log.w(TAG, "Guest user does not have the permission to change the WiFi network");
@@ -698,9 +559,7 @@ public class PanService extends ProfileService {
mPanDevices.remove(device);
}
}
- if (state == STATE_CONNECTED) {
- MetricsLogger.logProfileConnectionEvent(BluetoothMetricsProto.ProfileId.PAN);
- }
+
mAdapterService.updateProfileConnectionAdapterProperties(
device, BluetoothProfile.PAN, state, prevState);
diff --git a/android/app/src/com/android/bluetooth/pan/PanServiceBinder.java b/android/app/src/com/android/bluetooth/pan/PanServiceBinder.java
new file mode 100644
index 0000000000..e3baae21dc
--- /dev/null
+++ b/android/app/src/com/android/bluetooth/pan/PanServiceBinder.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.bluetooth.pan;
+
+import static android.Manifest.permission.BLUETOOTH_CONNECT;
+import static android.Manifest.permission.BLUETOOTH_PRIVILEGED;
+import static android.Manifest.permission.TETHER_PRIVILEGED;
+
+import android.annotation.RequiresPermission;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothPan;
+import android.bluetooth.IBluetoothPan;
+import android.bluetooth.IBluetoothPanCallback;
+import android.content.AttributionSource;
+import android.util.Log;
+
+import com.android.bluetooth.Utils;
+import com.android.bluetooth.btservice.ProfileService.IProfileServiceBinder;
+
+import java.util.Collections;
+import java.util.List;
+
+/** Handlers for incoming service calls */
+class PanServiceBinder extends IBluetoothPan.Stub implements IProfileServiceBinder {
+ private static final String TAG = PanServiceBinder.class.getSimpleName();
+
+ private PanService mService;
+
+ PanServiceBinder(PanService svc) {
+ mService = svc;
+ }
+
+ @Override
+ public void cleanup() {
+ mService = null;
+ }
+
+ @RequiresPermission(BLUETOOTH_CONNECT)
+ private PanService getService(AttributionSource source) {
+ if (Utils.isInstrumentationTestMode()) {
+ return mService;
+ }
+ if (!Utils.checkServiceAvailable(mService, TAG)
+ || !Utils.checkCallerIsSystemOrActiveOrManagedUser(mService, TAG)
+ || !Utils.checkConnectPermissionForDataDelivery(mService, source, TAG)) {
+ return null;
+ }
+ return mService;
+ }
+
+ @Override
+ public boolean connect(BluetoothDevice device, AttributionSource source) {
+ PanService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.connect(device);
+ }
+
+ @Override
+ public boolean disconnect(BluetoothDevice device, AttributionSource source) {
+ PanService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+ return service.disconnect(device);
+ }
+
+ @Override
+ public boolean setConnectionPolicy(
+ BluetoothDevice device, int connectionPolicy, AttributionSource source) {
+ PanService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.setConnectionPolicy(device, connectionPolicy);
+ }
+
+ @Override
+ public int getConnectionState(BluetoothDevice device, AttributionSource source) {
+ PanService service = getService(source);
+ if (service == null) {
+ return BluetoothPan.STATE_DISCONNECTED;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.getConnectionState(device);
+ }
+
+ @Override
+ public boolean isTetheringOn(AttributionSource source) {
+ // TODO(BT) have a variable marking the on/off state
+ PanService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+ return service.isTetheringOn();
+ }
+
+ @Override
+ public void setBluetoothTethering(
+ IBluetoothPanCallback callback, int id, boolean value, AttributionSource source) {
+ PanService service = getService(source);
+ if (service == null) {
+ return;
+ }
+
+ Log.d(
+ TAG,
+ "setBluetoothTethering:"
+ + (" value=" + value)
+ + (" pkgName= " + source.getPackageName())
+ + (" mTetherOn= " + service.isTetheringOn()));
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ service.enforceCallingOrSelfPermission(TETHER_PRIVILEGED, null);
+
+ service.setBluetoothTethering(callback, id, source.getUid(), value);
+ }
+
+ @Override
+ public List<BluetoothDevice> getConnectedDevices(AttributionSource source) {
+ PanService service = getService(source);
+ if (service == null) {
+ return Collections.emptyList();
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.getConnectedDevices();
+ }
+
+ @Override
+ public List<BluetoothDevice> getDevicesMatchingConnectionStates(
+ int[] states, AttributionSource source) {
+ PanService service = getService(source);
+ if (service == null) {
+ return Collections.emptyList();
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.getDevicesMatchingConnectionStates(states);
+ }
+}
diff --git a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapActivity.java b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapActivity.java
index 7223516e88..18fff92890 100644
--- a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapActivity.java
+++ b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapActivity.java
@@ -5,7 +5,7 @@
* 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
+ * 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,
diff --git a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapAuthenticator.java b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapAuthenticator.java
index 55419908eb..2e788d424a 100644
--- a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapAuthenticator.java
+++ b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapAuthenticator.java
@@ -5,7 +5,7 @@
* 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
+ * 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,
diff --git a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapCallLogComposer.java b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapCallLogComposer.java
index 85f07b687b..6ace2fb35c 100644
--- a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapCallLogComposer.java
+++ b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapCallLogComposer.java
@@ -39,6 +39,7 @@ import com.android.vcard.VCardUtils;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Calendar;
+import java.util.Locale;
/** VCard composer especially for Call Log used in Bluetooth. */
// Next tag value for ContentProfileErrorReportUtils.report(): 3
@@ -223,7 +224,7 @@ public class BluetoothPbapCallLogComposer implements AutoCloseable {
String rfc2455Format = "yyyyMMdd'T'HHmmss";
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(millSecs);
- SimpleDateFormat df = new SimpleDateFormat(rfc2455Format);
+ SimpleDateFormat df = new SimpleDateFormat(rfc2455Format, Locale.ROOT);
return df.format(cal.getTime());
}
diff --git a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapConfig.java b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapConfig.java
index 6fec2895e6..391d759065 100644
--- a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapConfig.java
+++ b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapConfig.java
@@ -5,7 +5,7 @@
* 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
+ * 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,
diff --git a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapObexServer.java b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapObexServer.java
index 88f7023b03..c5bb01f426 100644
--- a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapObexServer.java
+++ b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapObexServer.java
@@ -5,7 +5,7 @@
* 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
+ * 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,
diff --git a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapService.java b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapService.java
index 80f932a849..2d67fc9947 100644
--- a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapService.java
+++ b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapService.java
@@ -5,7 +5,7 @@
* 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
+ * 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,
@@ -17,7 +17,6 @@
package com.android.bluetooth.pbap;
import static android.Manifest.permission.BLUETOOTH_CONNECT;
-import static android.Manifest.permission.BLUETOOTH_PRIVILEGED;
import static android.bluetooth.BluetoothDevice.ACCESS_ALLOWED;
import static android.bluetooth.BluetoothDevice.ACCESS_REJECTED;
import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_ALLOWED;
@@ -28,19 +27,15 @@ import static com.android.bluetooth.Utils.joinUninterruptibly;
import static java.util.Objects.requireNonNull;
-import android.annotation.RequiresPermission;
import android.app.Activity;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
-import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothProtoEnums;
import android.bluetooth.BluetoothSocket;
import android.bluetooth.BluetoothUtils;
-import android.bluetooth.IBluetoothPbap;
-import android.content.AttributionSource;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -75,7 +70,6 @@ import com.android.bluetooth.util.DevicePolicyUtils;
import com.android.internal.annotations.VisibleForTesting;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -734,7 +728,7 @@ public class BluetoothPbapService extends ProfileService implements IObexConnect
@Override
protected IProfileServiceBinder initBinder() {
- return new PbapBinder(this);
+ return new BluetoothPbapServiceBinder(this);
}
@Override
@@ -756,11 +750,8 @@ public class BluetoothPbapService extends ProfileService implements IObexConnect
}
/**
- * Get the current instance of {@link BluetoothPbapService}
- *
* @return current instance of {@link BluetoothPbapService}
*/
- @VisibleForTesting
public static synchronized BluetoothPbapService getBluetoothPbapService() {
if (sBluetoothPbapService == null) {
Log.w(TAG, "getBluetoothPbapService(): service is null");
@@ -778,97 +769,6 @@ public class BluetoothPbapService extends ProfileService implements IObexConnect
sBluetoothPbapService = instance;
}
- @VisibleForTesting
- static class PbapBinder extends IBluetoothPbap.Stub implements IProfileServiceBinder {
- private BluetoothPbapService mService;
-
- PbapBinder(BluetoothPbapService service) {
- Log.v(TAG, "PbapBinder()");
- mService = service;
- }
-
- @Override
- public void cleanup() {
- mService = null;
- }
-
- @RequiresPermission(BLUETOOTH_CONNECT)
- private BluetoothPbapService getService(AttributionSource source) {
- // Cache mService because it can change while getService is called
- BluetoothPbapService service = mService;
-
- if (Utils.isInstrumentationTestMode()) {
- return service;
- }
-
- if (!Utils.checkServiceAvailable(service, TAG)
- || !Utils.checkCallerIsSystemOrActiveOrManagedUser(service, TAG)
- || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
- return null;
- }
-
- return service;
- }
-
- @Override
- public List<BluetoothDevice> getConnectedDevices(AttributionSource source) {
- Log.d(TAG, "getConnectedDevices");
- BluetoothPbapService service = getService(source);
- if (service == null) {
- return Collections.emptyList();
- }
- return service.getConnectedDevices();
- }
-
- @Override
- public List<BluetoothDevice> getDevicesMatchingConnectionStates(
- int[] states, AttributionSource source) {
- Log.d(TAG, "getDevicesMatchingConnectionStates");
- BluetoothPbapService service = getService(source);
- if (service == null) {
- return Collections.emptyList();
- }
- return service.getDevicesMatchingConnectionStates(states);
- }
-
- @Override
- public int getConnectionState(BluetoothDevice device, AttributionSource source) {
- Log.d(TAG, "getConnectionState: " + device);
- BluetoothPbapService service = getService(source);
- if (service == null) {
- return BluetoothAdapter.STATE_DISCONNECTED;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- return service.getConnectionState(device);
- }
-
- @Override
- public boolean setConnectionPolicy(
- BluetoothDevice device, int connectionPolicy, AttributionSource source) {
- Log.d(TAG, "setConnectionPolicy for device=" + device + " policy=" + connectionPolicy);
- BluetoothPbapService service = getService(source);
- if (service == null) {
- return false;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- return service.setConnectionPolicy(device, connectionPolicy);
- }
-
- @Override
- public void disconnect(BluetoothDevice device, AttributionSource source) {
- Log.d(TAG, "disconnect");
- BluetoothPbapService service = getService(source);
- if (service == null) {
- return;
- }
- service.disconnect(device);
- }
- }
-
@Override
public boolean onConnect(BluetoothDevice remoteDevice, BluetoothSocket socket) {
if (remoteDevice == null || socket == null) {
diff --git a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapServiceBinder.java b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapServiceBinder.java
new file mode 100644
index 0000000000..67ad07169a
--- /dev/null
+++ b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapServiceBinder.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.bluetooth.pbap;
+
+import static android.Manifest.permission.BLUETOOTH_CONNECT;
+import static android.Manifest.permission.BLUETOOTH_PRIVILEGED;
+
+import android.annotation.RequiresPermission;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.IBluetoothPbap;
+import android.content.AttributionSource;
+import android.util.Log;
+
+import com.android.bluetooth.Utils;
+import com.android.bluetooth.btservice.ProfileService.IProfileServiceBinder;
+
+import java.util.Collections;
+import java.util.List;
+
+class BluetoothPbapServiceBinder extends IBluetoothPbap.Stub implements IProfileServiceBinder {
+ private static final String TAG = BluetoothPbapServiceBinder.class.getSimpleName();
+
+ private BluetoothPbapService mService;
+
+ BluetoothPbapServiceBinder(BluetoothPbapService service) {
+ mService = service;
+ }
+
+ @Override
+ public void cleanup() {
+ mService = null;
+ }
+
+ @RequiresPermission(BLUETOOTH_CONNECT)
+ private BluetoothPbapService getService(AttributionSource source) {
+ BluetoothPbapService service = mService;
+
+ if (Utils.isInstrumentationTestMode()) {
+ return service;
+ }
+
+ if (!Utils.checkServiceAvailable(service, TAG)
+ || !Utils.checkCallerIsSystemOrActiveOrManagedUser(service, TAG)
+ || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
+ return null;
+ }
+
+ return service;
+ }
+
+ @Override
+ public List<BluetoothDevice> getConnectedDevices(AttributionSource source) {
+ Log.d(TAG, "getConnectedDevices");
+ BluetoothPbapService service = getService(source);
+ if (service == null) {
+ return Collections.emptyList();
+ }
+ return service.getConnectedDevices();
+ }
+
+ @Override
+ public List<BluetoothDevice> getDevicesMatchingConnectionStates(
+ int[] states, AttributionSource source) {
+ Log.d(TAG, "getDevicesMatchingConnectionStates");
+ BluetoothPbapService service = getService(source);
+ if (service == null) {
+ return Collections.emptyList();
+ }
+ return service.getDevicesMatchingConnectionStates(states);
+ }
+
+ @Override
+ public int getConnectionState(BluetoothDevice device, AttributionSource source) {
+ Log.d(TAG, "getConnectionState: " + device);
+ BluetoothPbapService service = getService(source);
+ if (service == null) {
+ return BluetoothAdapter.STATE_DISCONNECTED;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.getConnectionState(device);
+ }
+
+ @Override
+ public boolean setConnectionPolicy(
+ BluetoothDevice device, int connectionPolicy, AttributionSource source) {
+ Log.d(TAG, "setConnectionPolicy for device=" + device + " policy=" + connectionPolicy);
+ BluetoothPbapService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.setConnectionPolicy(device, connectionPolicy);
+ }
+
+ @Override
+ public void disconnect(BluetoothDevice device, AttributionSource source) {
+ Log.d(TAG, "disconnect");
+ BluetoothPbapService service = getService(source);
+ if (service == null) {
+ return;
+ }
+ service.disconnect(device);
+ }
+}
diff --git a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapSimVcardManager.java b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapSimVcardManager.java
index db427991a2..c63ec28105 100644
--- a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapSimVcardManager.java
+++ b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapSimVcardManager.java
@@ -5,7 +5,7 @@
* 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
+ * 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,
diff --git a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapUtils.java b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapUtils.java
index e70706f84d..75a1b3d9f8 100644
--- a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapUtils.java
+++ b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapUtils.java
@@ -5,7 +5,7 @@
* 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
+ * 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,
diff --git a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapVcardManager.java b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapVcardManager.java
index 5fa66a785c..c3b08a2e89 100644
--- a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapVcardManager.java
+++ b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapVcardManager.java
@@ -5,7 +5,7 @@
* 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
+ * 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,
diff --git a/android/app/src/com/android/bluetooth/pbap/HandlerForStringBuffer.java b/android/app/src/com/android/bluetooth/pbap/HandlerForStringBuffer.java
index 0d9a45b285..7d6333eea1 100644
--- a/android/app/src/com/android/bluetooth/pbap/HandlerForStringBuffer.java
+++ b/android/app/src/com/android/bluetooth/pbap/HandlerForStringBuffer.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/src/com/android/bluetooth/pbap/PbapStateMachine.java b/android/app/src/com/android/bluetooth/pbap/PbapStateMachine.java
index d0a756ac0d..b0c2d11a45 100644
--- a/android/app/src/com/android/bluetooth/pbap/PbapStateMachine.java
+++ b/android/app/src/com/android/bluetooth/pbap/PbapStateMachine.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017 The Android Open Source Project
+ * Copyright (C) 2017 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.
@@ -39,14 +39,12 @@ import android.os.Message;
import android.os.UserHandle;
import android.util.Log;
-import com.android.bluetooth.BluetoothMetricsProto;
import com.android.bluetooth.BluetoothObexTransport;
import com.android.bluetooth.BluetoothStatsLog;
import com.android.bluetooth.ObexRejectServer;
import com.android.bluetooth.R;
import com.android.bluetooth.Utils;
import com.android.bluetooth.btservice.AdapterService;
-import com.android.bluetooth.btservice.MetricsLogger;
import com.android.bluetooth.content_profiles.ContentProfileErrorReportUtils;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.annotations.VisibleForTesting.Visibility;
@@ -355,7 +353,6 @@ public class PbapStateMachine extends StateMachine {
Log.e(TAG, "Caught exception starting OBEX server session" + ex.toString());
}
broadcastStateTransitions();
- MetricsLogger.logProfileConnectionEvent(BluetoothMetricsProto.ProfileId.PBAP);
mService.setConnectionPolicy(mRemoteDevice, CONNECTION_POLICY_ALLOWED);
}
diff --git a/android/app/src/com/android/bluetooth/pbapclient/PbapClientContactsStorage.java b/android/app/src/com/android/bluetooth/pbapclient/PbapClientContactsStorage.java
index 9d064c7598..e0fb87f7a8 100644
--- a/android/app/src/com/android/bluetooth/pbapclient/PbapClientContactsStorage.java
+++ b/android/app/src/com/android/bluetooth/pbapclient/PbapClientContactsStorage.java
@@ -42,6 +42,7 @@ import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import java.util.Locale;
/**
* This class owns the interface to the contacts and call history storage mechanism, namely the
@@ -505,7 +506,7 @@ class PbapClientContactsStorage {
}
List<Pair<String, String>> irmc = call.getUnknownXData();
- SimpleDateFormat parser = new SimpleDateFormat(TIMESTAMP_FORMAT);
+ SimpleDateFormat parser = new SimpleDateFormat(TIMESTAMP_FORMAT, Locale.ROOT);
if (irmc != null) {
for (Pair<String, String> pair : irmc) {
if (pair.first.startsWith(CALL_LOG_TIMESTAMP_PROPERTY)) {
diff --git a/android/app/src/com/android/bluetooth/pbapclient/PbapClientService.java b/android/app/src/com/android/bluetooth/pbapclient/PbapClientService.java
index c83e856a72..9b75de98f0 100644
--- a/android/app/src/com/android/bluetooth/pbapclient/PbapClientService.java
+++ b/android/app/src/com/android/bluetooth/pbapclient/PbapClientService.java
@@ -173,7 +173,7 @@ public class PbapClientService extends ProfileService {
@Override
public IProfileServiceBinder initBinder() {
- return new PbapClientBinder(this);
+ return new PbapClientServiceBinder(this);
}
@Override
diff --git a/android/app/src/com/android/bluetooth/pbapclient/PbapClientBinder.java b/android/app/src/com/android/bluetooth/pbapclient/PbapClientServiceBinder.java
index f3bcd1e7b5..5a45896f02 100644
--- a/android/app/src/com/android/bluetooth/pbapclient/PbapClientBinder.java
+++ b/android/app/src/com/android/bluetooth/pbapclient/PbapClientServiceBinder.java
@@ -35,12 +35,12 @@ import java.util.Collections;
import java.util.List;
/** Handler for incoming service calls destined for PBAP Client */
-class PbapClientBinder extends IBluetoothPbapClient.Stub implements IProfileServiceBinder {
- private static final String TAG = PbapClientBinder.class.getSimpleName();
+class PbapClientServiceBinder extends IBluetoothPbapClient.Stub implements IProfileServiceBinder {
+ private static final String TAG = PbapClientServiceBinder.class.getSimpleName();
private PbapClientService mService;
- PbapClientBinder(PbapClientService service) {
+ PbapClientServiceBinder(PbapClientService service) {
mService = service;
}
diff --git a/android/app/src/com/android/bluetooth/pbapclient/PbapClientStateMachine.java b/android/app/src/com/android/bluetooth/pbapclient/PbapClientStateMachine.java
index d42cfec25e..ee09597feb 100644
--- a/android/app/src/com/android/bluetooth/pbapclient/PbapClientStateMachine.java
+++ b/android/app/src/com/android/bluetooth/pbapclient/PbapClientStateMachine.java
@@ -34,7 +34,6 @@ import android.os.Looper;
import android.os.Message;
import android.util.Log;
-import com.android.bluetooth.BluetoothMetricsProto;
import com.android.bluetooth.Utils;
import com.android.bluetooth.btservice.AdapterService;
import com.android.bluetooth.btservice.MetricsLogger;
@@ -908,9 +907,6 @@ class PbapClientStateMachine extends StateMachine {
private void onConnectionStateChanged(int state) {
int prevState = mCurrentState;
- if (prevState != state && state == STATE_CONNECTED) {
- MetricsLogger.logProfileConnectionEvent(BluetoothMetricsProto.ProfileId.PBAP_CLIENT);
- }
Intent intent = new Intent(BluetoothPbapClient.ACTION_CONNECTION_STATE_CHANGED);
intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, prevState);
diff --git a/android/app/src/com/android/bluetooth/pbapclient/PbapClientStateMachineOld.java b/android/app/src/com/android/bluetooth/pbapclient/PbapClientStateMachineOld.java
index 0576c30f5c..1cc8be9dbd 100644
--- a/android/app/src/com/android/bluetooth/pbapclient/PbapClientStateMachineOld.java
+++ b/android/app/src/com/android/bluetooth/pbapclient/PbapClientStateMachineOld.java
@@ -63,7 +63,6 @@ import android.os.Process;
import android.os.UserManager;
import android.util.Log;
-import com.android.bluetooth.BluetoothMetricsProto;
import com.android.bluetooth.Utils;
import com.android.bluetooth.btservice.AdapterService;
import com.android.bluetooth.btservice.MetricsLogger;
@@ -403,9 +402,6 @@ class PbapClientStateMachineOld extends StateMachine {
Log.w(TAG, "onConnectionStateChanged with invalid device");
return;
}
- if (prevState != state && state == STATE_CONNECTED) {
- MetricsLogger.logProfileConnectionEvent(BluetoothMetricsProto.ProfileId.PBAP_CLIENT);
- }
Log.d(TAG, "Connection state " + device + ": " + prevState + "->" + state);
AdapterService adapterService = AdapterService.getAdapterService();
if (adapterService != null) {
diff --git a/android/app/src/com/android/bluetooth/pbapclient/obex/CallLogPullRequest.java b/android/app/src/com/android/bluetooth/pbapclient/obex/CallLogPullRequest.java
index 3d276dd88b..aef9c9cef5 100644
--- a/android/app/src/com/android/bluetooth/pbapclient/obex/CallLogPullRequest.java
+++ b/android/app/src/com/android/bluetooth/pbapclient/obex/CallLogPullRequest.java
@@ -38,6 +38,7 @@ import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
+import java.util.Locale;
import java.util.Map;
public class CallLogPullRequest extends PullRequest {
@@ -106,7 +107,7 @@ public class CallLogPullRequest extends PullRequest {
}
}
List<Pair<String, String>> irmc = vcard.getUnknownXData();
- SimpleDateFormat parser = new SimpleDateFormat(TIMESTAMP_FORMAT);
+ SimpleDateFormat parser = new SimpleDateFormat(TIMESTAMP_FORMAT, Locale.ROOT);
if (irmc != null) {
for (Pair<String, String> pair : irmc) {
if (pair.first.startsWith(TIMESTAMP_PROPERTY)) {
diff --git a/android/app/src/com/android/bluetooth/sap/SapService.java b/android/app/src/com/android/bluetooth/sap/SapService.java
index 277acc4cf2..54391d24e3 100644
--- a/android/app/src/com/android/bluetooth/sap/SapService.java
+++ b/android/app/src/com/android/bluetooth/sap/SapService.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 The Android Open Source Project
+ * Copyright (C) 2024 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.
@@ -20,7 +20,6 @@ import static android.Manifest.permission.BLUETOOTH_CONNECT;
import static android.Manifest.permission.BLUETOOTH_PRIVILEGED;
import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_ALLOWED;
import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
-import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_UNKNOWN;
import static android.bluetooth.BluetoothProfile.STATE_CONNECTED;
import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTED;
@@ -37,8 +36,6 @@ import android.bluetooth.BluetoothSap;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.bluetooth.BluetoothUuid;
-import android.bluetooth.IBluetoothSap;
-import android.content.AttributionSource;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -52,18 +49,15 @@ import android.sysprop.BluetoothProperties;
import android.text.TextUtils;
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.MetricsLogger;
import com.android.bluetooth.btservice.ProfileService;
import com.android.bluetooth.sdp.SdpManagerNativeInterface;
import com.android.internal.annotations.VisibleForTesting;
import java.io.IOException;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.List;
public class SapService extends ProfileService implements AdapterService.BluetoothStateCallback {
@@ -539,9 +533,6 @@ public class SapService extends ProfileService implements AdapterService.Bluetoo
private synchronized void setState(int state, int result) {
if (state != mState) {
Log.d(TAG, "Sap state " + mState + " -> " + state + ", result = " + result);
- if (state == STATE_CONNECTED) {
- MetricsLogger.logProfileConnectionEvent(BluetoothMetricsProto.ProfileId.SAP);
- }
int prevState = mState;
mState = state;
mAdapterService.updateProfileConnectionAdapterProperties(
@@ -677,7 +668,7 @@ public class SapService extends ProfileService implements AdapterService.Bluetoo
@Override
protected IProfileServiceBinder initBinder() {
- return new SapBinder(this);
+ return new SapServiceBinder(this);
}
@Override
@@ -710,11 +701,8 @@ public class SapService extends ProfileService implements AdapterService.Bluetoo
}
/**
- * Get the current instance of {@link SapService}
- *
* @return current instance of {@link SapService}
*/
- @VisibleForTesting
public static synchronized SapService getSapService() {
if (sSapService == null) {
Log.w(TAG, "getSapService(): service is null");
@@ -889,145 +877,4 @@ public class SapService extends ProfileService implements AdapterService.Bluetoo
mSessionStatusHandler.sendEmptyMessage(MSG_SERVERSESSION_CLOSE);
}
}
-
- // Binder object: Must be static class or memory leak may occur
-
- /**
- * This class implements the IBluetoothSap interface - or actually it validates the
- * preconditions for calling the actual functionality in the SapService, and calls it.
- */
- private static class SapBinder extends IBluetoothSap.Stub implements IProfileServiceBinder {
- private SapService mService;
-
- SapBinder(SapService service) {
- Log.v(TAG, "SapBinder()");
- mService = service;
- }
-
- @Override
- public void cleanup() {
- mService = null;
- }
-
- @RequiresPermission(BLUETOOTH_CONNECT)
- private SapService getService(AttributionSource source) {
- // Cache mService because it can change while getService is called
- SapService service = mService;
-
- if (!Utils.checkServiceAvailable(service, TAG)
- || !Utils.checkCallerIsSystemOrActiveOrManagedUser(service, TAG)
- || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
- return null;
- }
-
- return service;
- }
-
- @Override
- public int getState(AttributionSource source) {
- Log.v(TAG, "getState()");
-
- SapService service = getService(source);
- if (service == null) {
- return BluetoothSap.STATE_DISCONNECTED;
- }
-
- return service.getState();
- }
-
- @Override
- public BluetoothDevice getClient(AttributionSource source) {
- Log.v(TAG, "getClient()");
-
- SapService service = getService(source);
- if (service == null) {
- return null;
- }
-
- Log.v(TAG, "getClient() - returning " + service.getRemoteDevice());
- return service.getRemoteDevice();
- }
-
- @Override
- public boolean isConnected(BluetoothDevice device, AttributionSource source) {
- Log.v(TAG, "isConnected()");
-
- SapService service = getService(source);
- if (service == null) {
- return false;
- }
-
- return service.getConnectionState(device) == STATE_CONNECTED;
- }
-
- @Override
- public boolean disconnect(BluetoothDevice device, AttributionSource source) {
- Log.v(TAG, "disconnect()");
-
- SapService service = getService(source);
- if (service == null) {
- return false;
- }
-
- return service.disconnect(device);
- }
-
- @Override
- public List<BluetoothDevice> getConnectedDevices(AttributionSource source) {
- Log.v(TAG, "getConnectedDevices()");
-
- SapService service = getService(source);
- if (service == null) {
- return Collections.emptyList();
- }
-
- return service.getConnectedDevices();
- }
-
- @Override
- public List<BluetoothDevice> getDevicesMatchingConnectionStates(
- int[] states, AttributionSource source) {
- Log.v(TAG, "getDevicesMatchingConnectionStates()");
-
- SapService service = getService(source);
- if (service == null) {
- return Collections.emptyList();
- }
-
- return service.getDevicesMatchingConnectionStates(states);
- }
-
- @Override
- public int getConnectionState(BluetoothDevice device, AttributionSource source) {
- Log.v(TAG, "getConnectionState()");
-
- SapService service = getService(source);
- if (service == null) {
- return STATE_DISCONNECTED;
- }
-
- return service.getConnectionState(device);
- }
-
- @Override
- public boolean setConnectionPolicy(
- BluetoothDevice device, int connectionPolicy, AttributionSource source) {
- SapService service = getService(source);
- if (service == null) {
- return false;
- }
-
- return service.setConnectionPolicy(device, connectionPolicy);
- }
-
- @Override
- public int getConnectionPolicy(BluetoothDevice device, AttributionSource source) {
- SapService service = getService(source);
- if (service == null) {
- return CONNECTION_POLICY_UNKNOWN;
- }
-
- return service.getConnectionPolicy(device);
- }
- }
}
diff --git a/android/app/src/com/android/bluetooth/sap/SapServiceBinder.java b/android/app/src/com/android/bluetooth/sap/SapServiceBinder.java
new file mode 100644
index 0000000000..4c8a96901a
--- /dev/null
+++ b/android/app/src/com/android/bluetooth/sap/SapServiceBinder.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.bluetooth.sap;
+
+import static android.Manifest.permission.BLUETOOTH_CONNECT;
+import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_UNKNOWN;
+import static android.bluetooth.BluetoothProfile.STATE_CONNECTED;
+import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTED;
+
+import android.annotation.RequiresPermission;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothSap;
+import android.bluetooth.IBluetoothSap;
+import android.content.AttributionSource;
+import android.util.Log;
+
+import com.android.bluetooth.Utils;
+import com.android.bluetooth.btservice.ProfileService.IProfileServiceBinder;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * This class implements the IBluetoothSap interface - or actually it validates the preconditions
+ * for calling the actual functionality in the SapService, and calls it.
+ */
+class SapServiceBinder extends IBluetoothSap.Stub implements IProfileServiceBinder {
+ private static final String TAG = SapServiceBinder.class.getSimpleName();
+
+ private SapService mService;
+
+ SapServiceBinder(SapService service) {
+ mService = service;
+ }
+
+ @Override
+ public void cleanup() {
+ mService = null;
+ }
+
+ @RequiresPermission(BLUETOOTH_CONNECT)
+ private SapService getService(AttributionSource source) {
+ SapService service = mService;
+
+ if (!Utils.checkServiceAvailable(service, TAG)
+ || !Utils.checkCallerIsSystemOrActiveOrManagedUser(service, TAG)
+ || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
+ return null;
+ }
+
+ return service;
+ }
+
+ @Override
+ public int getState(AttributionSource source) {
+ Log.v(TAG, "getState()");
+
+ SapService service = getService(source);
+ if (service == null) {
+ return BluetoothSap.STATE_DISCONNECTED;
+ }
+ return service.getState();
+ }
+
+ @Override
+ public BluetoothDevice getClient(AttributionSource source) {
+ Log.v(TAG, "getClient()");
+
+ SapService service = getService(source);
+ if (service == null) {
+ return null;
+ }
+
+ Log.v(TAG, "getClient() - returning " + service.getRemoteDevice());
+ return service.getRemoteDevice();
+ }
+
+ @Override
+ public boolean isConnected(BluetoothDevice device, AttributionSource source) {
+ Log.v(TAG, "isConnected()");
+
+ SapService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+ return service.getConnectionState(device) == STATE_CONNECTED;
+ }
+
+ @Override
+ public boolean disconnect(BluetoothDevice device, AttributionSource source) {
+ Log.v(TAG, "disconnect()");
+
+ SapService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+ return service.disconnect(device);
+ }
+
+ @Override
+ public List<BluetoothDevice> getConnectedDevices(AttributionSource source) {
+ Log.v(TAG, "getConnectedDevices()");
+
+ SapService service = getService(source);
+ if (service == null) {
+ return Collections.emptyList();
+ }
+ return service.getConnectedDevices();
+ }
+
+ @Override
+ public List<BluetoothDevice> getDevicesMatchingConnectionStates(
+ int[] states, AttributionSource source) {
+ Log.v(TAG, "getDevicesMatchingConnectionStates()");
+
+ SapService service = getService(source);
+ if (service == null) {
+ return Collections.emptyList();
+ }
+ return service.getDevicesMatchingConnectionStates(states);
+ }
+
+ @Override
+ public int getConnectionState(BluetoothDevice device, AttributionSource source) {
+ Log.v(TAG, "getConnectionState()");
+
+ SapService service = getService(source);
+ if (service == null) {
+ return STATE_DISCONNECTED;
+ }
+ return service.getConnectionState(device);
+ }
+
+ @Override
+ public boolean setConnectionPolicy(
+ BluetoothDevice device, int connectionPolicy, AttributionSource source) {
+ SapService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+ return service.setConnectionPolicy(device, connectionPolicy);
+ }
+
+ @Override
+ public int getConnectionPolicy(BluetoothDevice device, AttributionSource source) {
+ SapService service = getService(source);
+ if (service == null) {
+ return CONNECTION_POLICY_UNKNOWN;
+ }
+ return service.getConnectionPolicy(device);
+ }
+}
diff --git a/android/app/src/com/android/bluetooth/sdp/SdpManagerNativeInterface.java b/android/app/src/com/android/bluetooth/sdp/SdpManagerNativeInterface.java
index f009dd9c0e..e21d1e33e7 100644
--- a/android/app/src/com/android/bluetooth/sdp/SdpManagerNativeInterface.java
+++ b/android/app/src/com/android/bluetooth/sdp/SdpManagerNativeInterface.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 The Android Open Source Project
+ * Copyright (C) 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.
diff --git a/android/app/src/com/android/bluetooth/tbs/TbsGatt.java b/android/app/src/com/android/bluetooth/tbs/TbsGatt.java
index 23d62b3ec2..ce54586bd1 100644
--- a/android/app/src/com/android/bluetooth/tbs/TbsGatt.java
+++ b/android/app/src/com/android/bluetooth/tbs/TbsGatt.java
@@ -38,6 +38,7 @@ import android.util.Log;
import com.android.bluetooth.BluetoothEventLogger;
import com.android.bluetooth.Utils;
import com.android.bluetooth.btservice.AdapterService;
+import com.android.bluetooth.mcp.GattOpContext;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
@@ -147,32 +148,6 @@ public class TbsGatt {
public abstract boolean isInbandRingtoneEnabled(BluetoothDevice device);
}
- private record GattOpContext(
- Operation operation,
- int requestId,
- BluetoothGattCharacteristic characteristic,
- BluetoothGattDescriptor descriptor,
- boolean preparedWrite,
- boolean responseNeeded,
- int offset,
- ByteString value) {
- public enum Operation {
- READ_CHARACTERISTIC,
- WRITE_CHARACTERISTIC,
- READ_DESCRIPTOR,
- WRITE_DESCRIPTOR,
- }
-
- GattOpContext(
- Operation operation,
- int requestId,
- BluetoothGattCharacteristic characteristic,
- BluetoothGattDescriptor descriptor,
- int offset) {
- this(operation, requestId, characteristic, descriptor, false, false, offset, null);
- }
- }
-
TbsGatt(AdapterService adapterService, TbsService tbsService) {
this(adapterService, tbsService, new BluetoothGattServerProxy(adapterService));
}
@@ -983,56 +958,56 @@ public class TbsGatt {
@SuppressWarnings("EnumOrdinal")
private void onRejectedAuthorizationGattOperation(BluetoothDevice device, GattOpContext op) {
final UUID charUuid =
- (op.characteristic != null
- ? op.characteristic.getUuid()
- : (op.descriptor != null
- ? op.descriptor.getCharacteristic().getUuid()
+ (op.characteristic() != null
+ ? op.characteristic().getUuid()
+ : (op.descriptor() != null
+ ? op.descriptor().getCharacteristic().getUuid()
: null));
mEventLogger.logw(
TAG,
"onRejectedAuthorizationGattOperation device: "
+ device
+ ", opcode= "
- + op.operation
+ + op.operation()
+ ", characteristic= "
+ (charUuid != null ? tbsUuidToString(charUuid) : "UNKNOWN"));
- switch (op.operation) {
+ switch (op.operation()) {
case READ_CHARACTERISTIC:
case READ_DESCRIPTOR:
mBluetoothGattServer.sendResponse(
device,
- op.requestId,
+ op.requestId(),
BluetoothGatt.GATT_INSUFFICIENT_AUTHORIZATION,
- op.offset,
+ op.offset(),
null);
break;
case WRITE_CHARACTERISTIC:
- if (op.responseNeeded) {
+ if (op.responseNeeded()) {
mBluetoothGattServer.sendResponse(
device,
- op.requestId,
+ op.requestId(),
BluetoothGatt.GATT_INSUFFICIENT_AUTHORIZATION,
- op.offset,
+ op.offset(),
null);
} else {
// In case of control point operations we can send an application error code
- if (op.characteristic.getUuid().equals(UUID_CALL_CONTROL_POINT)) {
+ if (op.characteristic().getUuid().equals(UUID_CALL_CONTROL_POINT)) {
setCallControlPointResult(
device,
- op.operation.ordinal(),
+ op.operation().ordinal(),
0,
TbsGatt.CALL_CONTROL_POINT_RESULT_OPERATION_NOT_POSSIBLE);
}
}
break;
case WRITE_DESCRIPTOR:
- if (op.responseNeeded) {
+ if (op.responseNeeded()) {
mBluetoothGattServer.sendResponse(
device,
- op.requestId,
+ op.requestId(),
BluetoothGatt.GATT_INSUFFICIENT_AUTHORIZATION,
- op.offset,
+ op.offset(),
null);
}
break;
@@ -1043,7 +1018,7 @@ public class TbsGatt {
}
private void onUnauthorizedCharRead(BluetoothDevice device, GattOpContext op) {
- final UUID charUuid = op.characteristic.getUuid();
+ final UUID charUuid = op.characteristic().getUuid();
boolean allowToReadRealValue = false;
byte[] buffer = null;
@@ -1103,86 +1078,87 @@ public class TbsGatt {
}
if (allowToReadRealValue) {
- if (op.characteristic.getValue() != null) {
+ if (op.characteristic().getValue() != null) {
buffer =
Arrays.copyOfRange(
- op.characteristic.getValue(),
- op.offset,
- op.characteristic.getValue().length);
+ op.characteristic().getValue(),
+ op.offset(),
+ op.characteristic().getValue().length);
}
}
if (buffer != null) {
mBluetoothGattServer.sendResponse(
- device, op.requestId, BluetoothGatt.GATT_SUCCESS, op.offset, buffer);
+ device, op.requestId(), BluetoothGatt.GATT_SUCCESS, op.offset(), buffer);
} else {
mEventLogger.loge(
TAG, "Missing characteristic value for char: " + tbsUuidToString(charUuid));
mBluetoothGattServer.sendResponse(
device,
- op.requestId,
+ op.requestId(),
BluetoothGatt.GATT_INVALID_ATTRIBUTE_LENGTH,
- op.offset,
+ op.offset(),
buffer);
}
}
private void onUnauthorizedGattOperation(BluetoothDevice device, GattOpContext op) {
final UUID charUuid =
- (op.characteristic != null
- ? op.characteristic.getUuid()
- : (op.descriptor != null
- ? op.descriptor.getCharacteristic().getUuid()
+ (op.characteristic() != null
+ ? op.characteristic().getUuid()
+ : (op.descriptor() != null
+ ? op.descriptor().getCharacteristic().getUuid()
: null));
mEventLogger.logw(
TAG,
"onUnauthorizedGattOperation device: "
+ device
+ ", opcode= "
- + op.operation
+ + op.operation()
+ ", characteristic= "
+ (charUuid != null ? tbsUuidToString(charUuid) : "UNKNOWN"));
int status = BluetoothGatt.GATT_SUCCESS;
- switch (op.operation) {
+ switch (op.operation()) {
/* Allow not yet authorized devices to subscribe for notifications */
case READ_DESCRIPTOR:
- byte[] value = getCccBytes(device, op.descriptor.getCharacteristic().getUuid());
- if (value.length < op.offset) {
+ byte[] value = getCccBytes(device, op.descriptor().getCharacteristic().getUuid());
+ if (value.length < op.offset()) {
Log.e(
TAG,
("Wrong offset read for: "
- + op.descriptor.getCharacteristic().getUuid())
- + (": offset " + op.offset)
+ + op.descriptor().getCharacteristic().getUuid())
+ + (": offset " + op.offset())
+ (", total len: " + value.length));
status = BluetoothGatt.GATT_INVALID_OFFSET;
value = new byte[] {};
} else {
- value = Arrays.copyOfRange(value, op.offset, value.length);
+ value = Arrays.copyOfRange(value, op.offset(), value.length);
status = BluetoothGatt.GATT_SUCCESS;
}
- mBluetoothGattServer.sendResponse(device, op.requestId, status, op.offset, value);
+ mBluetoothGattServer.sendResponse(
+ device, op.requestId(), status, op.offset(), value);
return;
case WRITE_DESCRIPTOR:
- if (op.preparedWrite) {
+ if (op.preparedWrite()) {
status = BluetoothGatt.GATT_FAILURE;
- } else if (op.offset > 0) {
+ } else if (op.offset() > 0) {
status = BluetoothGatt.GATT_INVALID_OFFSET;
- } else if (op.value.toByteArray().length != 2) {
+ } else if (op.value().toByteArray().length != 2) {
status = BluetoothGatt.GATT_INVALID_ATTRIBUTE_LENGTH;
} else {
status = BluetoothGatt.GATT_SUCCESS;
setCcc(
device,
- op.descriptor.getCharacteristic().getUuid(),
- op.value.toByteArray());
+ op.descriptor().getCharacteristic().getUuid(),
+ op.value().toByteArray());
}
- if (op.responseNeeded) {
+ if (op.responseNeeded()) {
mBluetoothGattServer.sendResponse(
- device, op.requestId, status, op.offset, op.value.toByteArray());
+ device, op.requestId(), status, op.offset(), op.value().toByteArray());
}
return;
case READ_CHARACTERISTIC:
@@ -1212,17 +1188,17 @@ public class TbsGatt {
private void onAuthorizedGattOperation(BluetoothDevice device, GattOpContext op) {
final UUID charUuid =
- (op.characteristic != null
- ? op.characteristic.getUuid()
- : (op.descriptor != null
- ? op.descriptor.getCharacteristic().getUuid()
+ (op.characteristic() != null
+ ? op.characteristic().getUuid()
+ : (op.descriptor() != null
+ ? op.descriptor().getCharacteristic().getUuid()
: null));
mEventLogger.logd(
TAG,
"onAuthorizedGattOperation device: "
+ device
+ ", opcode= "
- + op.operation
+ + op.operation()
+ ", characteristic= "
+ (charUuid != null ? tbsUuidToString(charUuid) : "UNKNOWN"));
@@ -1230,7 +1206,7 @@ public class TbsGatt {
ClientCharacteristicConfigurationDescriptor cccd;
byte[] value;
- switch (op.operation) {
+ switch (op.operation()) {
case READ_CHARACTERISTIC:
Log.d(TAG, "onCharacteristicReadRequest: device=" + device);
@@ -1239,7 +1215,7 @@ public class TbsGatt {
return;
}
- if (op.characteristic.getUuid().equals(UUID_STATUS_FLAGS)) {
+ if (op.characteristic().getUuid().equals(UUID_STATUS_FLAGS)) {
value = new byte[2];
int valueInt = mSilentMode ? STATUS_FLAG_SILENT_MODE_ENABLED : 0;
if (mStatusFlagValue.containsKey(device)) {
@@ -1250,27 +1226,29 @@ public class TbsGatt {
value[0] = (byte) (valueInt & 0xFF);
value[1] = (byte) ((valueInt >> 8) & 0xFF);
} else {
- GattCharacteristic gattCharacteristic = (GattCharacteristic) op.characteristic;
+ GattCharacteristic gattCharacteristic =
+ (GattCharacteristic) op.characteristic();
value = gattCharacteristic.getValue();
if (value == null) {
value = new byte[0];
}
}
- if (value.length < op.offset) {
+ if (value.length < op.offset()) {
status = BluetoothGatt.GATT_INVALID_OFFSET;
Log.e(
TAG,
- ("Wrong offset read for: " + op.characteristic.getUuid())
- + (": offset " + op.offset)
+ ("Wrong offset read for: " + op.characteristic().getUuid())
+ + (": offset " + op.offset())
+ (", total len: " + value.length));
value = new byte[] {};
} else {
- value = Arrays.copyOfRange(value, op.offset, value.length);
+ value = Arrays.copyOfRange(value, op.offset(), value.length);
status = BluetoothGatt.GATT_SUCCESS;
}
- mBluetoothGattServer.sendResponse(device, op.requestId, status, op.offset, value);
+ mBluetoothGattServer.sendResponse(
+ device, op.requestId(), status, op.offset(), value);
break;
case WRITE_CHARACTERISTIC:
@@ -1281,20 +1259,20 @@ public class TbsGatt {
return;
}
- GattCharacteristic gattCharacteristic = (GattCharacteristic) op.characteristic;
- if (op.preparedWrite) {
+ GattCharacteristic gattCharacteristic = (GattCharacteristic) op.characteristic();
+ if (op.preparedWrite()) {
status = BluetoothGatt.GATT_FAILURE;
- } else if (op.offset > 0) {
+ } else if (op.offset() > 0) {
status = BluetoothGatt.GATT_INVALID_OFFSET;
} else {
gattCharacteristic.handleWriteRequest(
- device, op.requestId, op.responseNeeded, op.value.toByteArray());
+ device, op.requestId(), op.responseNeeded(), op.value().toByteArray());
return;
}
- if (op.responseNeeded) {
+ if (op.responseNeeded()) {
mBluetoothGattServer.sendResponse(
- device, op.requestId, status, op.offset, op.value.toByteArray());
+ device, op.requestId(), status, op.offset(), op.value().toByteArray());
}
break;
@@ -1306,17 +1284,18 @@ public class TbsGatt {
return;
}
- cccd = (ClientCharacteristicConfigurationDescriptor) op.descriptor;
+ cccd = (ClientCharacteristicConfigurationDescriptor) op.descriptor();
value = cccd.getValue(device);
- if (value.length < op.offset) {
+ if (value.length < op.offset()) {
status = BluetoothGatt.GATT_INVALID_OFFSET;
value = new byte[] {};
} else {
- value = Arrays.copyOfRange(value, op.offset, value.length);
+ value = Arrays.copyOfRange(value, op.offset(), value.length);
status = BluetoothGatt.GATT_SUCCESS;
}
- mBluetoothGattServer.sendResponse(device, op.requestId, status, op.offset, value);
+ mBluetoothGattServer.sendResponse(
+ device, op.requestId(), status, op.offset(), value);
break;
case WRITE_DESCRIPTOR:
@@ -1327,21 +1306,21 @@ public class TbsGatt {
return;
}
- cccd = (ClientCharacteristicConfigurationDescriptor) op.descriptor;
- if (op.preparedWrite) {
+ cccd = (ClientCharacteristicConfigurationDescriptor) op.descriptor();
+ if (op.preparedWrite()) {
// TODO: handle prepareWrite
status = BluetoothGatt.GATT_FAILURE;
- } else if (op.offset > 0) {
+ } else if (op.offset() > 0) {
status = BluetoothGatt.GATT_INVALID_OFFSET;
- } else if (op.value.toByteArray().length != 2) {
+ } else if (op.value().toByteArray().length != 2) {
status = BluetoothGatt.GATT_INVALID_ATTRIBUTE_LENGTH;
} else {
- status = cccd.setValue(device, op.value.toByteArray());
+ status = cccd.setValue(device, op.value().toByteArray());
}
- if (op.responseNeeded) {
+ if (op.responseNeeded()) {
mBluetoothGattServer.sendResponse(
- device, op.requestId, status, op.offset, op.value.toByteArray());
+ device, op.requestId(), status, op.offset(), op.value().toByteArray());
}
break;
diff --git a/android/app/src/com/android/bluetooth/tbs/TbsService.java b/android/app/src/com/android/bluetooth/tbs/TbsService.java
index ebd25f8229..3bb2fa45e7 100644
--- a/android/app/src/com/android/bluetooth/tbs/TbsService.java
+++ b/android/app/src/com/android/bluetooth/tbs/TbsService.java
@@ -17,19 +17,13 @@
package com.android.bluetooth.tbs;
-import static android.Manifest.permission.BLUETOOTH_CONNECT;
-import static android.Manifest.permission.BLUETOOTH_PRIVILEGED;
import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
import static java.util.Objects.requireNonNull;
-import android.annotation.RequiresPermission;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothLeCall;
-import android.bluetooth.IBluetoothLeCallControl;
import android.bluetooth.IBluetoothLeCallControlCallback;
-import android.content.AttributionSource;
-import android.os.ParcelUuid;
import android.os.RemoteException;
import android.sysprop.BluetoothProperties;
import android.util.Log;
@@ -38,7 +32,6 @@ import com.android.bluetooth.Utils;
import com.android.bluetooth.btservice.AdapterService;
import com.android.bluetooth.btservice.ProfileService;
import com.android.bluetooth.le_audio.LeAudioService;
-import com.android.internal.annotations.VisibleForTesting;
import java.util.HashMap;
import java.util.List;
@@ -68,7 +61,7 @@ public class TbsService extends ProfileService {
@Override
protected IProfileServiceBinder initBinder() {
- return new TbsServerBinder(this);
+ return new TbsServiceBinder(this);
}
@Override
@@ -206,105 +199,6 @@ public class TbsService extends ProfileService {
mTbsGeneric.clearInbandRingtoneSupport(device);
}
- /** Binder object: must be a static class or memory leak may occur */
- @VisibleForTesting
- static class TbsServerBinder extends IBluetoothLeCallControl.Stub
- implements IProfileServiceBinder {
- private TbsService mService;
-
- TbsServerBinder(TbsService service) {
- mService = service;
- }
-
- @Override
- public void cleanup() {
- mService = null;
- }
-
- @RequiresPermission(allOf = {BLUETOOTH_CONNECT, BLUETOOTH_PRIVILEGED})
- private TbsService getService(AttributionSource source) {
- // Cache mService because it can change while getService is called
- TbsService service = mService;
-
- if (!Utils.checkServiceAvailable(service, TAG)
- || !Utils.checkCallerIsSystemOrActiveOrManagedUser(service, TAG)
- || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
- return null;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- return service;
- }
-
- @Override
- public void registerBearer(
- String token,
- IBluetoothLeCallControlCallback callback,
- String uci,
- List<String> uriSchemes,
- int capabilities,
- String providerName,
- int technology,
- AttributionSource source) {
- TbsService service = getService(source);
- if (service != null) {
- service.registerBearer(
- token, callback, uci, uriSchemes, capabilities, providerName, technology);
- }
- }
-
- @Override
- public void unregisterBearer(String token, AttributionSource source) {
- TbsService service = getService(source);
- if (service != null) {
- service.unregisterBearer(token);
- }
- }
-
- @Override
- public void requestResult(int ccid, int requestId, int result, AttributionSource source) {
- TbsService service = getService(source);
- if (service != null) {
- service.requestResult(ccid, requestId, result);
- }
- }
-
- @Override
- public void callAdded(int ccid, BluetoothLeCall call, AttributionSource source) {
- TbsService service = getService(source);
- if (service != null) {
- service.callAdded(ccid, call);
- }
- }
-
- @Override
- public void callRemoved(int ccid, ParcelUuid callId, int reason, AttributionSource source) {
- TbsService service = getService(source);
- if (service != null) {
- service.callRemoved(ccid, callId.getUuid(), reason);
- }
- }
-
- @Override
- public void callStateChanged(
- int ccid, ParcelUuid callId, int state, AttributionSource source) {
- TbsService service = getService(source);
- if (service != null) {
- service.callStateChanged(ccid, callId.getUuid(), state);
- }
- }
-
- @Override
- public void currentCallsList(
- int ccid, List<BluetoothLeCall> calls, AttributionSource source) {
- TbsService service = getService(source);
- if (service != null) {
- service.currentCallsList(ccid, calls);
- }
- }
- }
-
- @VisibleForTesting
void registerBearer(
String token,
IBluetoothLeCallControlCallback callback,
@@ -335,42 +229,36 @@ public class TbsService extends ProfileService {
Log.d(TAG, "registerBearer: token=" + token + " success=" + success);
}
- @VisibleForTesting
void unregisterBearer(String token) {
Log.d(TAG, "unregisterBearer: token=" + token);
mTbsGeneric.removeBearer(token);
}
- @VisibleForTesting
public void requestResult(int ccid, int requestId, int result) {
Log.d(TAG, "requestResult: ccid=" + ccid + " requestId=" + requestId + " result=" + result);
mTbsGeneric.requestResult(ccid, requestId, result);
}
- @VisibleForTesting
void callAdded(int ccid, BluetoothLeCall call) {
Log.d(TAG, "callAdded: ccid=" + ccid + " call=" + call);
mTbsGeneric.callAdded(ccid, call);
}
- @VisibleForTesting
void callRemoved(int ccid, UUID callId, int reason) {
Log.d(TAG, "callRemoved: ccid=" + ccid + " callId=" + callId + " reason=" + reason);
mTbsGeneric.callRemoved(ccid, callId, reason);
}
- @VisibleForTesting
void callStateChanged(int ccid, UUID callId, int state) {
Log.d(TAG, "callStateChanged: ccid=" + ccid + " callId=" + callId + " state=" + state);
mTbsGeneric.callStateChanged(ccid, callId, state);
}
- @VisibleForTesting
void currentCallsList(int ccid, List<BluetoothLeCall> calls) {
Log.d(TAG, "currentCallsList: ccid=" + ccid + " calls=" + calls);
diff --git a/android/app/src/com/android/bluetooth/tbs/TbsServiceBinder.java b/android/app/src/com/android/bluetooth/tbs/TbsServiceBinder.java
new file mode 100644
index 0000000000..88a1a3435c
--- /dev/null
+++ b/android/app/src/com/android/bluetooth/tbs/TbsServiceBinder.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.bluetooth.tbs;
+
+import static android.Manifest.permission.BLUETOOTH_CONNECT;
+import static android.Manifest.permission.BLUETOOTH_PRIVILEGED;
+
+import android.annotation.RequiresPermission;
+import android.bluetooth.BluetoothLeCall;
+import android.bluetooth.IBluetoothLeCallControl;
+import android.bluetooth.IBluetoothLeCallControlCallback;
+import android.content.AttributionSource;
+import android.os.ParcelUuid;
+
+import com.android.bluetooth.Utils;
+import com.android.bluetooth.btservice.ProfileService.IProfileServiceBinder;
+
+import java.util.List;
+
+class TbsServiceBinder extends IBluetoothLeCallControl.Stub implements IProfileServiceBinder {
+ private static final String TAG = TbsServiceBinder.class.getSimpleName();
+
+ private TbsService mService;
+
+ TbsServiceBinder(TbsService service) {
+ mService = service;
+ }
+
+ @Override
+ public void cleanup() {
+ mService = null;
+ }
+
+ @RequiresPermission(allOf = {BLUETOOTH_CONNECT, BLUETOOTH_PRIVILEGED})
+ private TbsService getService(AttributionSource source) {
+ TbsService service = mService;
+
+ if (!Utils.checkServiceAvailable(service, TAG)
+ || !Utils.checkCallerIsSystemOrActiveOrManagedUser(service, TAG)
+ || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
+ return null;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service;
+ }
+
+ @Override
+ public void registerBearer(
+ String token,
+ IBluetoothLeCallControlCallback callback,
+ String uci,
+ List<String> uriSchemes,
+ int capabilities,
+ String providerName,
+ int technology,
+ AttributionSource source) {
+ TbsService service = getService(source);
+ if (service != null) {
+ service.registerBearer(
+ token, callback, uci, uriSchemes, capabilities, providerName, technology);
+ }
+ }
+
+ @Override
+ public void unregisterBearer(String token, AttributionSource source) {
+ TbsService service = getService(source);
+ if (service != null) {
+ service.unregisterBearer(token);
+ }
+ }
+
+ @Override
+ public void requestResult(int ccid, int requestId, int result, AttributionSource source) {
+ TbsService service = getService(source);
+ if (service != null) {
+ service.requestResult(ccid, requestId, result);
+ }
+ }
+
+ @Override
+ public void callAdded(int ccid, BluetoothLeCall call, AttributionSource source) {
+ TbsService service = getService(source);
+ if (service != null) {
+ service.callAdded(ccid, call);
+ }
+ }
+
+ @Override
+ public void callRemoved(int ccid, ParcelUuid callId, int reason, AttributionSource source) {
+ TbsService service = getService(source);
+ if (service != null) {
+ service.callRemoved(ccid, callId.getUuid(), reason);
+ }
+ }
+
+ @Override
+ public void callStateChanged(int ccid, ParcelUuid callId, int state, AttributionSource source) {
+ TbsService service = getService(source);
+ if (service != null) {
+ service.callStateChanged(ccid, callId.getUuid(), state);
+ }
+ }
+
+ @Override
+ public void currentCallsList(int ccid, List<BluetoothLeCall> calls, AttributionSource source) {
+ TbsService service = getService(source);
+ if (service != null) {
+ service.currentCallsList(ccid, calls);
+ }
+ }
+}
diff --git a/android/app/src/com/android/bluetooth/util/SystemProperties.java b/android/app/src/com/android/bluetooth/util/SystemProperties.java
index 29c5a1be7b..b508926daa 100644
--- a/android/app/src/com/android/bluetooth/util/SystemProperties.java
+++ b/android/app/src/com/android/bluetooth/util/SystemProperties.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2025 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/android/app/src/com/android/bluetooth/vc/VolumeControlNativeCallback.java b/android/app/src/com/android/bluetooth/vc/VolumeControlNativeCallback.java
index be86010bc2..a7b6234e6b 100644
--- a/android/app/src/com/android/bluetooth/vc/VolumeControlNativeCallback.java
+++ b/android/app/src/com/android/bluetooth/vc/VolumeControlNativeCallback.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 The Android Open Source Project
+ * Copyright (C) 2024 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.
diff --git a/android/app/src/com/android/bluetooth/vc/VolumeControlService.java b/android/app/src/com/android/bluetooth/vc/VolumeControlService.java
index 628a36b6e8..b21d4e19b3 100644
--- a/android/app/src/com/android/bluetooth/vc/VolumeControlService.java
+++ b/android/app/src/com/android/bluetooth/vc/VolumeControlService.java
@@ -17,8 +17,6 @@
package com.android.bluetooth.vc;
-import static android.Manifest.permission.BLUETOOTH_CONNECT;
-import static android.Manifest.permission.BLUETOOTH_PRIVILEGED;
import static android.bluetooth.BluetoothDevice.BOND_BONDED;
import static android.bluetooth.BluetoothDevice.BOND_NONE;
import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_ALLOWED;
@@ -36,19 +34,14 @@ import static com.android.bluetooth.flags.Flags.vcpDeviceVolumeApiImprovements;
import static java.util.Objects.requireNonNull;
import static java.util.Objects.requireNonNullElseGet;
-import android.annotation.RequiresPermission;
import android.bluetooth.AudioInputControl.AudioInputStatus;
import android.bluetooth.AudioInputControl.AudioInputType;
import android.bluetooth.AudioInputControl.GainMode;
import android.bluetooth.AudioInputControl.Mute;
-import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothUuid;
-import android.bluetooth.IAudioInputCallback;
-import android.bluetooth.IBluetoothVolumeControl;
import android.bluetooth.IBluetoothVolumeControlCallback;
-import android.content.AttributionSource;
import android.media.AudioManager;
import android.os.Handler;
import android.os.HandlerThread;
@@ -70,22 +63,13 @@ import com.android.bluetooth.le_audio.LeAudioService;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
-import libcore.util.SneakyThrow;
-
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Executors;
-import java.util.concurrent.FutureTask;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-import java.util.function.Function;
public class VolumeControlService extends ProfileService {
private static final String TAG = VolumeControlService.class.getSimpleName();
@@ -166,7 +150,7 @@ public class VolumeControlService extends ProfileService {
@Override
protected IProfileServiceBinder initBinder() {
- return new BluetoothVolumeControlBinder(this);
+ return new VolumeControlServiceBinder(this);
}
@Override
@@ -209,6 +193,14 @@ public class VolumeControlService extends ProfileService {
}
}
+ Handler getHandler() {
+ return mHandler;
+ }
+
+ Map<BluetoothDevice, VolumeControlInputDescriptor> getAudioInputs() {
+ return mAudioInputs;
+ }
+
/**
* Get the VolumeControlService instance
*
@@ -534,7 +526,6 @@ public class VolumeControlService extends ProfileService {
mNativeInterface.setExtAudioOutVolumeOffset(device, instanceId, volumeOffset);
}
- @VisibleForTesting
synchronized void setDeviceVolume(BluetoothDevice device, int volume, boolean isGroupOp) {
Log.d(
TAG,
@@ -1685,501 +1676,6 @@ public class VolumeControlService extends ProfileService {
BluetoothProfile.VOLUME_CONTROL, device, fromState, toState);
}
- /** Binder object: must be a static class or memory leak may occur */
- @VisibleForTesting
- static class BluetoothVolumeControlBinder extends IBluetoothVolumeControl.Stub
- implements IProfileServiceBinder {
- @VisibleForTesting boolean mIsTesting = false;
- private VolumeControlService mService;
-
- BluetoothVolumeControlBinder(VolumeControlService svc) {
- mService = svc;
- }
-
- @Override
- public void cleanup() {
- mService = null;
- }
-
- @RequiresPermission(BLUETOOTH_CONNECT)
- private VolumeControlService getService(AttributionSource source) {
- requireNonNull(source);
-
- // Cache mService because it can change while getService is called
- VolumeControlService service = mService;
-
- if (Utils.isInstrumentationTestMode()) {
- return service;
- }
-
- if (!Utils.checkServiceAvailable(service, TAG)
- || !Utils.checkCallerIsSystemOrActiveOrManagedUser(service, TAG)
- || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
- return null;
- }
-
- return service;
- }
-
- @Override
- public List<BluetoothDevice> getConnectedDevices(AttributionSource source) {
- VolumeControlService service = getService(source);
- if (service == null) {
- return Collections.emptyList();
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- return service.getConnectedDevices();
- }
-
- @Override
- public List<BluetoothDevice> getDevicesMatchingConnectionStates(
- int[] states, AttributionSource source) {
- VolumeControlService service = getService(source);
- if (service == null) {
- return Collections.emptyList();
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- return service.getDevicesMatchingConnectionStates(states);
- }
-
- @Override
- public int getConnectionState(BluetoothDevice device, AttributionSource source) {
- requireNonNull(device);
-
- VolumeControlService service = getService(source);
- if (service == null) {
- return STATE_DISCONNECTED;
- }
-
- return service.getConnectionState(device);
- }
-
- @Override
- public boolean setConnectionPolicy(
- BluetoothDevice device, int connectionPolicy, AttributionSource source) {
- requireNonNull(device);
-
- VolumeControlService service = getService(source);
- if (service == null) {
- return false;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- return service.setConnectionPolicy(device, connectionPolicy);
- }
-
- @Override
- public int getConnectionPolicy(BluetoothDevice device, AttributionSource source) {
- requireNonNull(device);
-
- VolumeControlService service = getService(source);
- if (service == null) {
- return CONNECTION_POLICY_UNKNOWN;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- return service.getConnectionPolicy(device);
- }
-
- @Override
- public boolean isVolumeOffsetAvailable(BluetoothDevice device, AttributionSource source) {
- requireNonNull(device);
-
- VolumeControlService service = getService(source);
- if (service == null) {
- return false;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- return service.isVolumeOffsetAvailable(device);
- }
-
- @Override
- public int getNumberOfVolumeOffsetInstances(
- BluetoothDevice device, AttributionSource source) {
- requireNonNull(device);
-
- VolumeControlService service = getService(source);
- if (service == null) {
- return 0;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- return service.getNumberOfVolumeOffsetInstances(device);
- }
-
- @Override
- public void setVolumeOffset(
- BluetoothDevice device,
- int instanceId,
- int volumeOffset,
- AttributionSource source) {
- requireNonNull(device);
-
- VolumeControlService service = getService(source);
- if (service == null) {
- return;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- service.setVolumeOffset(device, instanceId, volumeOffset);
- }
-
- @Override
- public void setDeviceVolume(
- BluetoothDevice device, int volume, boolean isGroupOp, AttributionSource source) {
- requireNonNull(device);
-
- VolumeControlService service = getService(source);
- if (service == null) {
- return;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- service.setDeviceVolume(device, volume, isGroupOp);
- }
-
- @Override
- public void setGroupVolume(int groupId, int volume, AttributionSource source) {
- VolumeControlService service = getService(source);
- if (service == null) {
- return;
- }
-
- service.setGroupVolume(groupId, volume);
- }
-
- @Override
- public int getGroupVolume(int groupId, AttributionSource source) {
- VolumeControlService service = getService(source);
- if (service == null) {
- return 0;
- }
-
- return service.getGroupVolume(groupId);
- }
-
- @Override
- public void setGroupActive(int groupId, boolean active, AttributionSource source) {
- VolumeControlService service = getService(source);
- if (service == null) {
- return;
- }
-
- service.setGroupActive(groupId, active);
- }
-
- @Override
- public void mute(BluetoothDevice device, AttributionSource source) {
- requireNonNull(device);
-
- VolumeControlService service = getService(source);
- if (service == null) {
- return;
- }
-
- service.mute(device);
- }
-
- @Override
- public void muteGroup(int groupId, AttributionSource source) {
- VolumeControlService service = getService(source);
- if (service == null) {
- return;
- }
-
- service.muteGroup(groupId);
- }
-
- @Override
- public void unmute(BluetoothDevice device, AttributionSource source) {
- requireNonNull(device);
-
- VolumeControlService service = getService(source);
- if (service == null) {
- return;
- }
-
- service.unmute(device);
- }
-
- @Override
- public void unmuteGroup(int groupId, AttributionSource source) {
- VolumeControlService service = getService(source);
- if (service == null) {
- return;
- }
-
- service.unmuteGroup(groupId);
- }
-
- private static void postAndWait(Handler handler, Runnable runnable) {
- FutureTask<Void> task = new FutureTask(Executors.callable(runnable));
-
- handler.post(task);
- try {
- task.get(1, TimeUnit.SECONDS);
- } catch (TimeoutException | InterruptedException e) {
- SneakyThrow.sneakyThrow(e);
- } catch (ExecutionException e) {
- SneakyThrow.sneakyThrow(e.getCause());
- }
- }
-
- @Override
- public void registerCallback(
- IBluetoothVolumeControlCallback callback, AttributionSource source) {
- requireNonNull(callback);
-
- VolumeControlService service = getService(source);
- if (service == null) {
- return;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- postAndWait(service.mHandler, () -> service.registerCallback(callback));
- }
-
- @Override
- public void unregisterCallback(
- IBluetoothVolumeControlCallback callback, AttributionSource source) {
- requireNonNull(callback);
-
- VolumeControlService service = getService(source);
- if (service == null) {
- return;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- postAndWait(service.mHandler, () -> service.unregisterCallback(callback));
- }
-
- @Override
- public void notifyNewRegisteredCallback(
- IBluetoothVolumeControlCallback callback, AttributionSource source) {
- requireNonNull(callback);
-
- VolumeControlService service = getService(source);
- if (service == null) {
- return;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
- postAndWait(service.mHandler, () -> service.notifyNewRegisteredCallback(callback));
- }
-
- private static void validateBluetoothDevice(BluetoothDevice device) {
- requireNonNull(device);
- String address = device.getAddress();
- if (!BluetoothAdapter.checkBluetoothAddress(address)) {
- throw new IllegalArgumentException("Invalid device address: " + address);
- }
- }
-
- @RequiresPermission(allOf = {BLUETOOTH_CONNECT, BLUETOOTH_PRIVILEGED})
- private <R> R aicsWrapper(
- AttributionSource source,
- BluetoothDevice device,
- Function<VolumeControlInputDescriptor, R> fn,
- R defaultValue) {
- validateBluetoothDevice(device);
-
- VolumeControlService service = getService(source);
- if (service == null) {
- return defaultValue;
- }
-
- service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
-
- VolumeControlInputDescriptor inputs = service.mAudioInputs.get(device);
- if (inputs == null) {
- Log.w(TAG, "No audio inputs for " + device);
- return defaultValue;
- }
-
- return fn.apply(inputs);
- }
-
- @Override
- public int getNumberOfAudioInputControlServices(
- AttributionSource source, BluetoothDevice device) {
- validateBluetoothDevice(device);
- Log.d(TAG, "getNumberOfAudioInputControlServices(" + device + ")");
- return aicsWrapper(source, device, i -> i.size(), 0);
- }
-
- @Override
- public void registerAudioInputControlCallback(
- AttributionSource source,
- BluetoothDevice device,
- int instanceId,
- IAudioInputCallback callback) {
- requireNonNull(callback);
- Log.d(
- TAG,
- "registerAudioInputControlCallback("
- + (device + ", " + instanceId + ", " + callback)
- + ")");
- aicsWrapper(
- source,
- device,
- i -> {
- i.registerCallback(instanceId, callback);
- return null;
- },
- null);
- }
-
- @Override
- public void unregisterAudioInputControlCallback(
- AttributionSource source,
- BluetoothDevice device,
- int instanceId,
- IAudioInputCallback callback) {
- requireNonNull(callback);
- Log.d(
- TAG,
- "unregisterAudioInputControlCallback("
- + (device + ", " + instanceId + ", " + callback)
- + ")");
- aicsWrapper(
- source,
- device,
- i -> {
- i.unregisterCallback(instanceId, callback);
- return null;
- },
- null);
- }
-
- @Override
- public int getAudioInputGainSettingUnit(
- AttributionSource source, BluetoothDevice device, int instanceId) {
- Log.d(TAG, "getAudioInputGainSettingUnit(" + device + ", " + instanceId + ")");
- return aicsWrapper(source, device, i -> i.getGainSettingUnit(instanceId), 0);
- }
-
- @Override
- public int getAudioInputGainSettingMin(
- AttributionSource source, BluetoothDevice device, int instanceId) {
- Log.d(TAG, "getAudioInputGainSettingMin(" + device + ", " + instanceId + ")");
- return aicsWrapper(source, device, i -> i.getGainSettingMin(instanceId), 0);
- }
-
- @Override
- public int getAudioInputGainSettingMax(
- AttributionSource source, BluetoothDevice device, int instanceId) {
- Log.d(TAG, "getAudioInputGainSettingMax(" + device + ", " + instanceId + ")");
- return aicsWrapper(source, device, i -> i.getGainSettingMax(instanceId), 0);
- }
-
- @Override
- public String getAudioInputDescription(
- AttributionSource source, BluetoothDevice device, int instanceId) {
- Log.d(TAG, "getAudioInputDescription(" + device + ", " + instanceId + ")");
- return aicsWrapper(source, device, i -> i.getDescription(instanceId), "");
- }
-
- @Override
- public boolean isAudioInputDescriptionWritable(
- AttributionSource source, BluetoothDevice device, int instanceId) {
- Log.d(TAG, "isAudioInputDescriptionWritable(" + device + ", " + instanceId + ")");
- return aicsWrapper(source, device, i -> i.isDescriptionWritable(instanceId), false);
- }
-
- @Override
- public boolean setAudioInputDescription(
- AttributionSource source,
- BluetoothDevice device,
- int instanceId,
- String description) {
- requireNonNull(description);
- Log.d(TAG, "setAudioInputDescription(" + device + ", " + instanceId + ")");
- return aicsWrapper(
- source, device, i -> i.setDescription(instanceId, description), false);
- }
-
- @Override
- public @AudioInputStatus int getAudioInputStatus(
- AttributionSource source, BluetoothDevice device, int instanceId) {
- Log.d(TAG, "getAudioInputStatus(" + device + ", " + instanceId + ")");
- return aicsWrapper(
- source,
- device,
- i -> i.getStatus(instanceId),
- (int) bluetooth.constants.aics.AudioInputStatus.INACTIVE);
- }
-
- @Override
- public @AudioInputType int getAudioInputType(
- AttributionSource source, BluetoothDevice device, int instanceId) {
- Log.d(TAG, "getAudioInputType(" + device + ", " + instanceId + ")");
- return aicsWrapper(
- source,
- device,
- i -> i.getType(instanceId),
- bluetooth.constants.AudioInputType.UNSPECIFIED);
- }
-
- @Override
- public int getAudioInputGainSetting(
- AttributionSource source, BluetoothDevice device, int instanceId) {
- Log.d(TAG, "getAudioInputGainSetting(" + device + ", " + instanceId + ")");
- return aicsWrapper(source, device, i -> i.getGainSetting(instanceId), 0);
- }
-
- @Override
- public boolean setAudioInputGainSetting(
- AttributionSource source, BluetoothDevice device, int instanceId, int gainSetting) {
- Log.d(TAG, "setAudioInputGainSetting(" + device + ", " + instanceId + ")");
- return aicsWrapper(
- source, device, i -> i.setGainSetting(instanceId, gainSetting), false);
- }
-
- @Override
- public @GainMode int getAudioInputGainMode(
- AttributionSource source, BluetoothDevice device, int instanceId) {
- Log.d(TAG, "getAudioInputGainMode(" + device + ", " + instanceId + ")");
- return aicsWrapper(
- source,
- device,
- i -> i.getGainMode(instanceId),
- (int) bluetooth.constants.aics.GainMode.AUTOMATIC_ONLY);
- }
-
- @Override
- public boolean setAudioInputGainMode(
- AttributionSource source,
- BluetoothDevice device,
- int instanceId,
- @GainMode int gainMode) {
- Log.d(TAG, "setAudioInputGainMode(" + device + ", " + instanceId + ")");
- return aicsWrapper(source, device, i -> i.setGainMode(instanceId, gainMode), false);
- }
-
- @Override
- public @Mute int getAudioInputMute(
- AttributionSource source, BluetoothDevice device, int instanceId) {
- Log.d(TAG, "getAudioInputMute(" + device + ", " + instanceId + ")");
- return aicsWrapper(
- source,
- device,
- i -> i.getMute(instanceId),
- (int) bluetooth.constants.aics.Mute.DISABLED);
- }
-
- @Override
- public boolean setAudioInputMute(
- AttributionSource source, BluetoothDevice device, int instanceId, @Mute int mute) {
- Log.d(TAG, "setAudioInputMute(" + device + ", " + instanceId + ")");
- return aicsWrapper(source, device, i -> i.setMute(instanceId, mute), false);
- }
- }
-
@Override
public void dump(StringBuilder sb) {
super.dump(sb);
diff --git a/android/app/src/com/android/bluetooth/vc/VolumeControlServiceBinder.java b/android/app/src/com/android/bluetooth/vc/VolumeControlServiceBinder.java
new file mode 100644
index 0000000000..7438ab14cd
--- /dev/null
+++ b/android/app/src/com/android/bluetooth/vc/VolumeControlServiceBinder.java
@@ -0,0 +1,528 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.bluetooth.vc;
+
+import static android.Manifest.permission.BLUETOOTH_CONNECT;
+import static android.Manifest.permission.BLUETOOTH_PRIVILEGED;
+import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_UNKNOWN;
+import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTED;
+
+import static java.util.Objects.requireNonNull;
+
+import android.annotation.RequiresPermission;
+import android.bluetooth.AudioInputControl.AudioInputStatus;
+import android.bluetooth.AudioInputControl.AudioInputType;
+import android.bluetooth.AudioInputControl.GainMode;
+import android.bluetooth.AudioInputControl.Mute;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.IAudioInputCallback;
+import android.bluetooth.IBluetoothVolumeControl;
+import android.bluetooth.IBluetoothVolumeControlCallback;
+import android.content.AttributionSource;
+import android.os.Handler;
+import android.util.Log;
+
+import com.android.bluetooth.Utils;
+import com.android.bluetooth.btservice.ProfileService.IProfileServiceBinder;
+import com.android.internal.annotations.VisibleForTesting;
+
+import libcore.util.SneakyThrow;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Executors;
+import java.util.concurrent.FutureTask;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.function.Function;
+
+class VolumeControlServiceBinder extends IBluetoothVolumeControl.Stub
+ implements IProfileServiceBinder {
+ private static final String TAG = VolumeControlServiceBinder.class.getSimpleName();
+
+ @VisibleForTesting boolean mIsTesting = false;
+ private VolumeControlService mService;
+
+ VolumeControlServiceBinder(VolumeControlService svc) {
+ mService = svc;
+ }
+
+ @Override
+ public void cleanup() {
+ mService = null;
+ }
+
+ @RequiresPermission(BLUETOOTH_CONNECT)
+ private VolumeControlService getService(AttributionSource source) {
+ requireNonNull(source);
+
+ VolumeControlService service = mService;
+
+ if (Utils.isInstrumentationTestMode()) {
+ return service;
+ }
+
+ if (!Utils.checkServiceAvailable(service, TAG)
+ || !Utils.checkCallerIsSystemOrActiveOrManagedUser(service, TAG)
+ || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
+ return null;
+ }
+
+ return service;
+ }
+
+ @Override
+ public List<BluetoothDevice> getConnectedDevices(AttributionSource source) {
+ VolumeControlService service = getService(source);
+ if (service == null) {
+ return Collections.emptyList();
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.getConnectedDevices();
+ }
+
+ @Override
+ public List<BluetoothDevice> getDevicesMatchingConnectionStates(
+ int[] states, AttributionSource source) {
+ VolumeControlService service = getService(source);
+ if (service == null) {
+ return Collections.emptyList();
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.getDevicesMatchingConnectionStates(states);
+ }
+
+ @Override
+ public int getConnectionState(BluetoothDevice device, AttributionSource source) {
+ requireNonNull(device);
+
+ VolumeControlService service = getService(source);
+ if (service == null) {
+ return STATE_DISCONNECTED;
+ }
+ return service.getConnectionState(device);
+ }
+
+ @Override
+ public boolean setConnectionPolicy(
+ BluetoothDevice device, int connectionPolicy, AttributionSource source) {
+ requireNonNull(device);
+
+ VolumeControlService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.setConnectionPolicy(device, connectionPolicy);
+ }
+
+ @Override
+ public int getConnectionPolicy(BluetoothDevice device, AttributionSource source) {
+ requireNonNull(device);
+
+ VolumeControlService service = getService(source);
+ if (service == null) {
+ return CONNECTION_POLICY_UNKNOWN;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.getConnectionPolicy(device);
+ }
+
+ @Override
+ public boolean isVolumeOffsetAvailable(BluetoothDevice device, AttributionSource source) {
+ requireNonNull(device);
+
+ VolumeControlService service = getService(source);
+ if (service == null) {
+ return false;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.isVolumeOffsetAvailable(device);
+ }
+
+ @Override
+ public int getNumberOfVolumeOffsetInstances(BluetoothDevice device, AttributionSource source) {
+ requireNonNull(device);
+
+ VolumeControlService service = getService(source);
+ if (service == null) {
+ return 0;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ return service.getNumberOfVolumeOffsetInstances(device);
+ }
+
+ @Override
+ public void setVolumeOffset(
+ BluetoothDevice device, int instanceId, int volumeOffset, AttributionSource source) {
+ requireNonNull(device);
+
+ VolumeControlService service = getService(source);
+ if (service == null) {
+ return;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ service.setVolumeOffset(device, instanceId, volumeOffset);
+ }
+
+ @Override
+ public void setDeviceVolume(
+ BluetoothDevice device, int volume, boolean isGroupOp, AttributionSource source) {
+ requireNonNull(device);
+
+ VolumeControlService service = getService(source);
+ if (service == null) {
+ return;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ service.setDeviceVolume(device, volume, isGroupOp);
+ }
+
+ @Override
+ public void setGroupVolume(int groupId, int volume, AttributionSource source) {
+ VolumeControlService service = getService(source);
+ if (service == null) {
+ return;
+ }
+ service.setGroupVolume(groupId, volume);
+ }
+
+ @Override
+ public int getGroupVolume(int groupId, AttributionSource source) {
+ VolumeControlService service = getService(source);
+ if (service == null) {
+ return 0;
+ }
+ return service.getGroupVolume(groupId);
+ }
+
+ @Override
+ public void setGroupActive(int groupId, boolean active, AttributionSource source) {
+ VolumeControlService service = getService(source);
+ if (service == null) {
+ return;
+ }
+ service.setGroupActive(groupId, active);
+ }
+
+ @Override
+ public void mute(BluetoothDevice device, AttributionSource source) {
+ requireNonNull(device);
+
+ VolumeControlService service = getService(source);
+ if (service == null) {
+ return;
+ }
+ service.mute(device);
+ }
+
+ @Override
+ public void muteGroup(int groupId, AttributionSource source) {
+ VolumeControlService service = getService(source);
+ if (service == null) {
+ return;
+ }
+ service.muteGroup(groupId);
+ }
+
+ @Override
+ public void unmute(BluetoothDevice device, AttributionSource source) {
+ requireNonNull(device);
+
+ VolumeControlService service = getService(source);
+ if (service == null) {
+ return;
+ }
+ service.unmute(device);
+ }
+
+ @Override
+ public void unmuteGroup(int groupId, AttributionSource source) {
+ VolumeControlService service = getService(source);
+ if (service == null) {
+ return;
+ }
+ service.unmuteGroup(groupId);
+ }
+
+ private static void postAndWait(Handler handler, Runnable runnable) {
+ FutureTask<Void> task = new FutureTask(Executors.callable(runnable));
+
+ handler.post(task);
+ try {
+ task.get(1, TimeUnit.SECONDS);
+ } catch (TimeoutException | InterruptedException e) {
+ SneakyThrow.sneakyThrow(e);
+ } catch (ExecutionException e) {
+ SneakyThrow.sneakyThrow(e.getCause());
+ }
+ }
+
+ @Override
+ public void registerCallback(
+ IBluetoothVolumeControlCallback callback, AttributionSource source) {
+ requireNonNull(callback);
+
+ VolumeControlService service = getService(source);
+ if (service == null) {
+ return;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ postAndWait(service.getHandler(), () -> service.registerCallback(callback));
+ }
+
+ @Override
+ public void unregisterCallback(
+ IBluetoothVolumeControlCallback callback, AttributionSource source) {
+ requireNonNull(callback);
+
+ VolumeControlService service = getService(source);
+ if (service == null) {
+ return;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ postAndWait(service.getHandler(), () -> service.unregisterCallback(callback));
+ }
+
+ @Override
+ public void notifyNewRegisteredCallback(
+ IBluetoothVolumeControlCallback callback, AttributionSource source) {
+ requireNonNull(callback);
+
+ VolumeControlService service = getService(source);
+ if (service == null) {
+ return;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+ postAndWait(service.getHandler(), () -> service.notifyNewRegisteredCallback(callback));
+ }
+
+ private static void validateBluetoothDevice(BluetoothDevice device) {
+ requireNonNull(device);
+ String address = device.getAddress();
+ if (!BluetoothAdapter.checkBluetoothAddress(address)) {
+ throw new IllegalArgumentException("Invalid device address: " + address);
+ }
+ }
+
+ @RequiresPermission(allOf = {BLUETOOTH_CONNECT, BLUETOOTH_PRIVILEGED})
+ private <R> R aicsWrapper(
+ AttributionSource source,
+ BluetoothDevice device,
+ Function<VolumeControlInputDescriptor, R> fn,
+ R defaultValue) {
+ validateBluetoothDevice(device);
+
+ VolumeControlService service = getService(source);
+ if (service == null) {
+ return defaultValue;
+ }
+
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+
+ VolumeControlInputDescriptor inputs = service.getAudioInputs().get(device);
+ if (inputs == null) {
+ Log.w(TAG, "No audio inputs for " + device);
+ return defaultValue;
+ }
+
+ return fn.apply(inputs);
+ }
+
+ @Override
+ public int getNumberOfAudioInputControlServices(
+ AttributionSource source, BluetoothDevice device) {
+ validateBluetoothDevice(device);
+ Log.d(TAG, "getNumberOfAudioInputControlServices(" + device + ")");
+ return aicsWrapper(source, device, i -> i.size(), 0);
+ }
+
+ @Override
+ public void registerAudioInputControlCallback(
+ AttributionSource source,
+ BluetoothDevice device,
+ int instanceId,
+ IAudioInputCallback callback) {
+ requireNonNull(callback);
+ Log.d(
+ TAG,
+ "registerAudioInputControlCallback("
+ + (device + ", " + instanceId + ", " + callback)
+ + ")");
+ aicsWrapper(
+ source,
+ device,
+ i -> {
+ i.registerCallback(instanceId, callback);
+ return null;
+ },
+ null);
+ }
+
+ @Override
+ public void unregisterAudioInputControlCallback(
+ AttributionSource source,
+ BluetoothDevice device,
+ int instanceId,
+ IAudioInputCallback callback) {
+ requireNonNull(callback);
+ Log.d(
+ TAG,
+ "unregisterAudioInputControlCallback("
+ + (device + ", " + instanceId + ", " + callback)
+ + ")");
+ aicsWrapper(
+ source,
+ device,
+ i -> {
+ i.unregisterCallback(instanceId, callback);
+ return null;
+ },
+ null);
+ }
+
+ @Override
+ public int getAudioInputGainSettingUnit(
+ AttributionSource source, BluetoothDevice device, int instanceId) {
+ Log.d(TAG, "getAudioInputGainSettingUnit(" + device + ", " + instanceId + ")");
+ return aicsWrapper(source, device, i -> i.getGainSettingUnit(instanceId), 0);
+ }
+
+ @Override
+ public int getAudioInputGainSettingMin(
+ AttributionSource source, BluetoothDevice device, int instanceId) {
+ Log.d(TAG, "getAudioInputGainSettingMin(" + device + ", " + instanceId + ")");
+ return aicsWrapper(source, device, i -> i.getGainSettingMin(instanceId), 0);
+ }
+
+ @Override
+ public int getAudioInputGainSettingMax(
+ AttributionSource source, BluetoothDevice device, int instanceId) {
+ Log.d(TAG, "getAudioInputGainSettingMax(" + device + ", " + instanceId + ")");
+ return aicsWrapper(source, device, i -> i.getGainSettingMax(instanceId), 0);
+ }
+
+ @Override
+ public String getAudioInputDescription(
+ AttributionSource source, BluetoothDevice device, int instanceId) {
+ Log.d(TAG, "getAudioInputDescription(" + device + ", " + instanceId + ")");
+ return aicsWrapper(source, device, i -> i.getDescription(instanceId), "");
+ }
+
+ @Override
+ public boolean isAudioInputDescriptionWritable(
+ AttributionSource source, BluetoothDevice device, int instanceId) {
+ Log.d(TAG, "isAudioInputDescriptionWritable(" + device + ", " + instanceId + ")");
+ return aicsWrapper(source, device, i -> i.isDescriptionWritable(instanceId), false);
+ }
+
+ @Override
+ public boolean setAudioInputDescription(
+ AttributionSource source, BluetoothDevice device, int instanceId, String description) {
+ requireNonNull(description);
+ Log.d(TAG, "setAudioInputDescription(" + device + ", " + instanceId + ")");
+ return aicsWrapper(source, device, i -> i.setDescription(instanceId, description), false);
+ }
+
+ @Override
+ public @AudioInputStatus int getAudioInputStatus(
+ AttributionSource source, BluetoothDevice device, int instanceId) {
+ Log.d(TAG, "getAudioInputStatus(" + device + ", " + instanceId + ")");
+ return aicsWrapper(
+ source,
+ device,
+ i -> i.getStatus(instanceId),
+ (int) bluetooth.constants.aics.AudioInputStatus.INACTIVE);
+ }
+
+ @Override
+ public @AudioInputType int getAudioInputType(
+ AttributionSource source, BluetoothDevice device, int instanceId) {
+ Log.d(TAG, "getAudioInputType(" + device + ", " + instanceId + ")");
+ return aicsWrapper(
+ source,
+ device,
+ i -> i.getType(instanceId),
+ bluetooth.constants.AudioInputType.UNSPECIFIED);
+ }
+
+ @Override
+ public int getAudioInputGainSetting(
+ AttributionSource source, BluetoothDevice device, int instanceId) {
+ Log.d(TAG, "getAudioInputGainSetting(" + device + ", " + instanceId + ")");
+ return aicsWrapper(source, device, i -> i.getGainSetting(instanceId), 0);
+ }
+
+ @Override
+ public boolean setAudioInputGainSetting(
+ AttributionSource source, BluetoothDevice device, int instanceId, int gainSetting) {
+ Log.d(TAG, "setAudioInputGainSetting(" + device + ", " + instanceId + ")");
+ return aicsWrapper(source, device, i -> i.setGainSetting(instanceId, gainSetting), false);
+ }
+
+ @Override
+ public @GainMode int getAudioInputGainMode(
+ AttributionSource source, BluetoothDevice device, int instanceId) {
+ Log.d(TAG, "getAudioInputGainMode(" + device + ", " + instanceId + ")");
+ return aicsWrapper(
+ source,
+ device,
+ i -> i.getGainMode(instanceId),
+ (int) bluetooth.constants.aics.GainMode.AUTOMATIC_ONLY);
+ }
+
+ @Override
+ public boolean setAudioInputGainMode(
+ AttributionSource source,
+ BluetoothDevice device,
+ int instanceId,
+ @GainMode int gainMode) {
+ Log.d(TAG, "setAudioInputGainMode(" + device + ", " + instanceId + ")");
+ return aicsWrapper(source, device, i -> i.setGainMode(instanceId, gainMode), false);
+ }
+
+ @Override
+ public @Mute int getAudioInputMute(
+ AttributionSource source, BluetoothDevice device, int instanceId) {
+ Log.d(TAG, "getAudioInputMute(" + device + ", " + instanceId + ")");
+ return aicsWrapper(
+ source,
+ device,
+ i -> i.getMute(instanceId),
+ (int) bluetooth.constants.aics.Mute.DISABLED);
+ }
+
+ @Override
+ public boolean setAudioInputMute(
+ AttributionSource source, BluetoothDevice device, int instanceId, @Mute int mute) {
+ Log.d(TAG, "setAudioInputMute(" + device + ", " + instanceId + ")");
+ return aicsWrapper(source, device, i -> i.setMute(instanceId, mute), false);
+ }
+}
diff --git a/android/app/tests/instrumentation/com/android/bluetooth/opp/BluetoothOppLauncherActivityTest.java b/android/app/tests/instrumentation/com/android/bluetooth/opp/BluetoothOppLauncherActivityTest.java
index fd9531105b..7bb7bbfbc3 100644
--- a/android/app/tests/instrumentation/com/android/bluetooth/opp/BluetoothOppLauncherActivityTest.java
+++ b/android/app/tests/instrumentation/com/android/bluetooth/opp/BluetoothOppLauncherActivityTest.java
@@ -46,6 +46,7 @@ import android.net.Uri;
import android.platform.test.annotations.RequiresFlagsDisabled;
import android.platform.test.annotations.RequiresFlagsEnabled;
import android.platform.test.flag.junit.CheckFlagsRule;
+import android.provider.Settings;
import android.sysprop.BluetoothProperties;
import androidx.lifecycle.Lifecycle;
@@ -382,6 +383,30 @@ public class BluetoothOppLauncherActivityTest {
assertThat(argument.getValue().getData()).isEqualTo(Uri.EMPTY);
}
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_SEND_OPP_DEVICE_PICKER_EXTRA_INTENT)
+ public void onCreate_withActionSend_grantUriPermissionToNearbyComponent() {
+ doReturn(true).when(mMethodProxy).bluetoothAdapterIsEnabled(any());
+ doReturn(PackageManager.PERMISSION_GRANTED)
+ .when(mMethodProxy)
+ .componentCallerCheckContentUriPermission(any(), any(), anyInt());
+ String uriString = "content://test.provider/1";
+ Settings.Secure.putString(
+ mTargetContext.getContentResolver(),
+ "nearby_sharing_component",
+ "com.example/.BComponent");
+
+ ActivityScenario<BluetoothOppLauncherActivity> unused =
+ ActivityScenario.launch(createSendIntent(uriString));
+
+ verify(mMethodProxy)
+ .grantUriPermission(
+ any(),
+ eq("com.example"),
+ eq(Uri.parse(uriString)),
+ eq(Intent.FLAG_GRANT_READ_URI_PERMISSION));
+ }
+
@Ignore("b/263724420")
@Test
public void launchDevicePicker_bluetoothNotEnabled_launchEnableActivity() throws Exception {
diff --git a/android/app/tests/unit/Android.bp b/android/app/tests/unit/Android.bp
index 01d195cc43..a5b7dc36c8 100644
--- a/android/app/tests/unit/Android.bp
+++ b/android/app/tests/unit/Android.bp
@@ -35,6 +35,7 @@ android_test {
"androidx.room_room-runtime",
"androidx.room_room-testing",
"androidx.test.espresso.intents",
+ "androidx.test.ext.junit",
"androidx.test.ext.truth",
"androidx.test.rules",
"androidx.test.uiautomator_uiautomator",
@@ -45,6 +46,7 @@ android_test {
"gson",
"guava-android-testlib",
"mmslib",
+ "mockito-kotlin2",
"mockito-target-extended",
"modules-utils-handlerexecutor",
"platform-parametric-runner-lib",
@@ -61,8 +63,11 @@ android_test {
jarjar_rules: ":bluetooth-jarjar-rules",
asset_dirs: ["src/com/android/bluetooth/btservice/storage/schemas"],
- // Include all test java files.
- srcs: ["src/**/*.java"],
+ // Include all test java and kotlin files.
+ srcs: [
+ "src/**/*.java",
+ "src/**/*.kt",
+ ],
jacoco: {
include_filter: ["android.bluetooth.*"],
exclude_filter: [],
diff --git a/android/app/tests/unit/src/com/android/bluetooth/ObexAppParametersTest.java b/android/app/tests/unit/src/com/android/bluetooth/ObexAppParametersTest.java
index c7bb30475e..1166a4ae10 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/ObexAppParametersTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/ObexAppParametersTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/SignedLongLongTest.java b/android/app/tests/unit/src/com/android/bluetooth/SignedLongLongTest.java
index 8a887b71eb..00b4306532 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/SignedLongLongTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/SignedLongLongTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 The Android Open Source Project
+ * Copyright (C) 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/TestUtils.java b/android/app/tests/unit/src/com/android/bluetooth/TestUtils.java
index cb61bc2853..e3ffd072d3 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/TestUtils.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/TestUtils.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 The Android Open Source Project
+ * Copyright (C) 2018 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/UtilsTest.java b/android/app/tests/unit/src/com/android/bluetooth/UtilsTest.java
index ebada2d9a4..b8e26ed03b 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/UtilsTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/UtilsTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -47,7 +47,7 @@ import java.nio.ByteOrder;
import java.nio.charset.StandardCharsets;
import java.util.UUID;
-/** Test for Utils.java */
+/** Test cases for {@link Utils}. */
@SmallTest
@RunWith(AndroidJUnit4.class)
public class UtilsTest {
@@ -66,13 +66,6 @@ public class UtilsTest {
}
@Test
- public void byteArrayToString() {
- byte[] valueBuf = new byte[] {0x01, 0x02};
- String str = Utils.byteArrayToString(valueBuf);
- assertThat(str).isEqualTo("01 02");
- }
-
- @Test
public void uuidsToByteArray() {
ParcelUuid[] uuids =
new ParcelUuid[] {
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 d0c253523a..8f5dd839ae 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
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 eb3def2b89..65d00773ba 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -36,15 +36,20 @@ import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.platform.test.flag.junit.SetFlagsRule;
+import androidx.test.filters.SmallTest;
+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;
+/** Test cases for {@link A2dpServiceBinder} */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
public class A2dpServiceBinderTest {
- private static final AttributionSource sSource = new AttributionSource.Builder(0).build();
- private static final BluetoothDevice sDevice = getTestDevice(0);
@Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
@@ -53,7 +58,10 @@ public class A2dpServiceBinderTest {
@Mock private A2dpService mA2dpService;
@Mock private PackageManager mPackageManager;
- private A2dpService.BluetoothA2dpBinder mBinder;
+ private final AttributionSource sSource = new AttributionSource.Builder(0).build();
+ private final BluetoothDevice sDevice = getTestDevice(0);
+
+ private A2dpServiceBinder mBinder;
@Before
public void setUp() throws Exception {
@@ -62,7 +70,7 @@ public class A2dpServiceBinderTest {
appInfo.targetSdkVersion = android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
doReturn(appInfo).when(mPackageManager).getApplicationInfo(any(), anyInt());
- mBinder = new A2dpService.BluetoothA2dpBinder(mA2dpService);
+ mBinder = new A2dpServiceBinder(mA2dpService);
}
@After
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 f336cf6a69..b2fb43b362 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 The Android Open Source Project
+ * Copyright (C) 2018 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.
@@ -111,8 +111,7 @@ public class A2dpServiceTest {
@Parameters(name = "{0}")
public static List<FlagsParameterization> getParams() {
- return FlagsParameterization.allCombinationsOf(
- Flags.FLAG_A2DP_BROADCAST_CONNECTION_STATE_WHEN_TURNED_OFF);
+ return FlagsParameterization.allCombinationsOf();
}
public A2dpServiceTest(FlagsParameterization flags) {
@@ -194,11 +193,9 @@ public class A2dpServiceTest {
mA2dpService.cleanup();
dispatchAtLeastOneMessage();
- if (Flags.a2dpBroadcastConnectionStateWhenTurnedOff()) {
- // Verify that the intent CONNECTION_STATE_CHANGED is generated
- // for the existing connections.
- verifyConnectionStateIntent(mDevice, STATE_DISCONNECTED, STATE_CONNECTED);
- }
+ // Verify that the intent CONNECTION_STATE_CHANGED is generated
+ // for the existing connections.
+ verifyConnectionStateIntent(mDevice, STATE_DISCONNECTED, STATE_CONNECTED);
// Verify that setActiveDevice(null) was called during shutdown
verify(mMockNativeInterface).setActiveDevice(null);
@@ -641,11 +638,9 @@ public class A2dpServiceTest {
assertThat(mA2dpService.getDevices()).contains(mDevice);
// Device unbond - state machine is not removed
mA2dpService.bondStateChangedFromTest(mDevice, BluetoothDevice.BOND_NONE);
- if (Flags.a2dpBroadcastConnectionStateWhenTurnedOff()) {
- // Verify that the intent CONNECTION_STATE_CHANGED is generated
- // for the existing connections.
- verifyConnectionStateIntent(mDevice, STATE_DISCONNECTED, STATE_CONNECTING);
- }
+ // Verify that the intent CONNECTION_STATE_CHANGED is generated
+ // for the existing connections.
+ verifyConnectionStateIntent(mDevice, STATE_DISCONNECTED, STATE_CONNECTING);
assertThat(mA2dpService.getDevices()).doesNotContain(mDevice);
// A2DP stack event: CONNECTION_STATE_CONNECTED - state machine is not removed
@@ -656,11 +651,9 @@ public class A2dpServiceTest {
assertThat(mA2dpService.getDevices()).contains(mDevice);
// Device unbond - state machine is not removed
mA2dpService.bondStateChangedFromTest(mDevice, BluetoothDevice.BOND_NONE);
- if (Flags.a2dpBroadcastConnectionStateWhenTurnedOff()) {
- // Verify that the intent CONNECTION_STATE_CHANGED is generated
- // for the existing connections.
- verifyConnectionStateIntent(mDevice, STATE_DISCONNECTED, STATE_CONNECTED);
- }
+ // Verify that the intent CONNECTION_STATE_CHANGED is generated
+ // for the existing connections.
+ verifyConnectionStateIntent(mDevice, STATE_DISCONNECTED, STATE_CONNECTED);
assertThat(mA2dpService.getDevices()).doesNotContain(mDevice);
// A2DP stack event: CONNECTION_STATE_DISCONNECTING - state machine is not removed
@@ -672,11 +665,9 @@ public class A2dpServiceTest {
assertThat(mA2dpService.getDevices()).contains(mDevice);
// Device unbond - state machine is not removed
mA2dpService.bondStateChangedFromTest(mDevice, BluetoothDevice.BOND_NONE);
- if (Flags.a2dpBroadcastConnectionStateWhenTurnedOff()) {
- // Verify that the intent CONNECTION_STATE_CHANGED is generated
- // for the existing connections.
- verifyConnectionStateIntent(mDevice, STATE_DISCONNECTED, STATE_DISCONNECTING);
- }
+ // Verify that the intent CONNECTION_STATE_CHANGED is generated
+ // for the existing connections.
+ verifyConnectionStateIntent(mDevice, STATE_DISCONNECTED, STATE_DISCONNECTING);
assertThat(mA2dpService.getDevices()).doesNotContain(mDevice);
// A2DP stack event: CONNECTION_STATE_DISCONNECTED - state machine is not removed
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 d51bae8f63..c44094bd2c 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2017 The Android Open Source Project
+ * Copyright (C) 2017 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.
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 24ead6e4b8..6f7723caa9 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -27,21 +27,29 @@ import static org.mockito.Mockito.verify;
import android.bluetooth.BluetoothDevice;
import android.content.AttributionSource;
+import androidx.test.filters.SmallTest;
+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;
+/** Test cases for {@link A2dpSinkServiceBinder} */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
public class A2dpSinkServiceBinderTest {
+
@Rule public final MockitoRule mMockitoRule = new MockitoRule();
@Mock private A2dpSinkService mService;
- private A2dpSinkService.A2dpSinkServiceBinder mBinder;
+ private A2dpSinkServiceBinder mBinder;
@Before
public void setUp() throws Exception {
- mBinder = new A2dpSinkService.A2dpSinkServiceBinder(mService);
+ mBinder = new A2dpSinkServiceBinder(mService);
}
@After
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 5ea9ad1d94..8b108c65e5 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 The Android Open Source Project
+ * Copyright (C) 2018 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.
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 5d13e09c9b..5641fbe7fc 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2021 The Android Open Source Project
+ * Copyright (C) 2021 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/a2dpsink/StackEventTest.java b/android/app/tests/unit/src/com/android/bluetooth/a2dpsink/StackEventTest.java
index b4944c2324..5a0b67d77e 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/a2dpsink/StackEventTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/a2dpsink/StackEventTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2021 The Android Open Source Project
+ * Copyright (C) 2021 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.
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 ab08c8bafc..47109d6b16 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 The Android Open Source Project
+ * Copyright (C) 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.
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 dfa391c909..7d77021833 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2017 The Android Open Source Project
+ * Copyright (C) 2017 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/audio_util/GPMWrapperTest.java b/android/app/tests/unit/src/com/android/bluetooth/audio_util/GPMWrapperTest.java
index f6ae8a4fd3..74d63bddbf 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/audio_util/GPMWrapperTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/audio_util/GPMWrapperTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 The Android Open Source Project
+ * Copyright (C) 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.
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 d74b4ecd5b..a74a0e7789 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
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 29a3fc2be5..c7d5458ca2 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
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 20784033c2..ca7d227747 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2017 The Android Open Source Project
+ * Copyright (C) 2017 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.
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 df6efa4a56..b0ac35637d 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/audio_util/UtilTest.java b/android/app/tests/unit/src/com/android/bluetooth/audio_util/UtilTest.java
index bac99cd389..ff1b79e9a5 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/audio_util/UtilTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/audio_util/UtilTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/avrcp/AvrcpBipObexServerTest.java b/android/app/tests/unit/src/com/android/bluetooth/avrcp/AvrcpBipObexServerTest.java
index 73978edd1e..d67e19ee60 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/avrcp/AvrcpBipObexServerTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/avrcp/AvrcpBipObexServerTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/avrcp/AvrcpCoverArtStorageTest.java b/android/app/tests/unit/src/com/android/bluetooth/avrcp/AvrcpCoverArtStorageTest.java
index 4b0a53be21..46e24db940 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/avrcp/AvrcpCoverArtStorageTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/avrcp/AvrcpCoverArtStorageTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/avrcp/AvrcpTargetServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/avrcp/AvrcpTargetServiceTest.java
index 611a04eac6..1111e05af7 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/avrcp/AvrcpTargetServiceTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/avrcp/AvrcpTargetServiceTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 The Android Open Source Project
+ * Copyright (C) 2024 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.
@@ -23,8 +23,8 @@ import static com.android.bluetooth.TestUtils.mockGetSystemService;
import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.anyString;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.verify;
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 f1e54d5cd2..4ce83f3a56 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 The Android Open Source Project
+ * Copyright (C) 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/avrcp/CoverArtTest.java b/android/app/tests/unit/src/com/android/bluetooth/avrcp/CoverArtTest.java
index bcf90f4066..1312a589aa 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/avrcp/CoverArtTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/avrcp/CoverArtTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
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 d88f8122be..16360b5cce 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerNativeInterfaceTest.java b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerNativeInterfaceTest.java
index 38938e8472..6364c499a4 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerNativeInterfaceTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerNativeInterfaceTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 The Android Open Source Project
+ * Copyright (C) 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.
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 dd12985a44..efd371dfdd 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -34,41 +34,41 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
+/** Test cases for {@link AvrcpControllerServiceBinder} */
@SmallTest
@RunWith(AndroidJUnit4.class)
public class AvrcpControllerServiceBinderTest {
+
@Rule public final MockitoRule mMockitoRule = new MockitoRule();
@Mock private AvrcpControllerService mService;
private final BluetoothDevice mDevice = getTestDevice(49);
- AvrcpControllerService.AvrcpControllerServiceBinder mBinder;
+ private AvrcpControllerServiceBinder mBinder;
@Before
public void setUp() throws Exception {
- mBinder = new AvrcpControllerService.AvrcpControllerServiceBinder(mService);
+ mBinder = new AvrcpControllerServiceBinder(mService);
}
@Test
public void getConnectedDevices_callsServiceMethod() {
mBinder.getConnectedDevices(null);
-
verify(mService).getConnectedDevices();
}
@Test
public void getDevicesMatchingConnectionStates_callsServiceMethod() {
int[] states = new int[] {STATE_CONNECTED};
- mBinder.getDevicesMatchingConnectionStates(states, null);
+ mBinder.getDevicesMatchingConnectionStates(states, null);
verify(mService).getDevicesMatchingConnectionStates(states);
}
@Test
public void getConnectionState_callsServiceMethod() {
mBinder.getConnectionState(mDevice, null);
-
verify(mService).getConnectionState(mDevice);
}
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 8c745987be..ee46a1accd 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 The Android Open Source Project
+ * Copyright (C) 2018 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.
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 ee30dfa8d1..43688601fe 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
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 02b563adbf..b2fbbe132f 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtStorageTest.java b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtStorageTest.java
index 98d00ebe5d..33aa418fda 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtStorageTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtStorageTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpItemTest.java b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpItemTest.java
index dbadfc526a..40c03dd0ae 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpItemTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpItemTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
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 c1b0f52616..95d12cb2a1 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/BrowseNodeTest.java b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/BrowseNodeTest.java
index dab7613a9a..aa06d75c77 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/BrowseNodeTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/BrowseNodeTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/BrowseTreeTest.java b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/BrowseTreeTest.java
index 680f74b0c7..5d359d1ef4 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/BrowseTreeTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/BrowseTreeTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/PlayerApplicationSettingsTest.java b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/PlayerApplicationSettingsTest.java
index 782621d77a..a106f6e97f 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/PlayerApplicationSettingsTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/PlayerApplicationSettingsTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/StackEventTest.java b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/StackEventTest.java
index 82fe7c6162..ded802cbb7 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/StackEventTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/StackEventTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipAttachmentFormatTest.java b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipAttachmentFormatTest.java
index 03afb2826a..68b06e5c95 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipAttachmentFormatTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipAttachmentFormatTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipDatetimeTest.java b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipDatetimeTest.java
index 5d93884efb..abdee02e65 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipDatetimeTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipDatetimeTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipEncodingTest.java b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipEncodingTest.java
index 712c304c33..dd6c498679 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipEncodingTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipEncodingTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipImageDescriptorTest.java b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipImageDescriptorTest.java
index 8d0415dcaa..0d87190643 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipImageDescriptorTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipImageDescriptorTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipImageFormatTest.java b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipImageFormatTest.java
index 75d04f6c8b..2ee0bda8bb 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipImageFormatTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipImageFormatTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipImagePropertiesTest.java b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipImagePropertiesTest.java
index 8f11f9218f..a1c9829273 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipImagePropertiesTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipImagePropertiesTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipImageTest.java b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipImageTest.java
index 4a8f103ad1..ca98f02d21 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipImageTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipImageTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipPixelTest.java b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipPixelTest.java
index 8d2146218a..1f47f0c606 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipPixelTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipPixelTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipTransformationTest.java b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipTransformationTest.java
index 031a71c81e..7d5eb5a986 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipTransformationTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/BipTransformationTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/RequestGetImagePropertiesTest.java b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/RequestGetImagePropertiesTest.java
index fb833c757b..9633aa4f95 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/RequestGetImagePropertiesTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/RequestGetImagePropertiesTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/RequestGetImageTest.java b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/RequestGetImageTest.java
index d68854b91e..4d5ca54dfb 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/RequestGetImageTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/bip/RequestGetImageTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/bas/BatteryServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/bas/BatteryServiceTest.java
index 3e0212223d..84c9640524 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/bas/BatteryServiceTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/bas/BatteryServiceTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/bas/BatteryStateMachineTest.java b/android/app/tests/unit/src/com/android/bluetooth/bas/BatteryStateMachineTest.java
index cf24333f8f..5e439f826b 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/bas/BatteryStateMachineTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/bas/BatteryStateMachineTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/bass_client/BaseDataTest.java b/android/app/tests/unit/src/com/android/bluetooth/bass_client/BaseDataTest.java
index 2b993cc4aa..c8305744e2 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/bass_client/BaseDataTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/bass_client/BaseDataTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
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/BassClientServiceBinderTest.java
index d51e857efe..584f0cdeea 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/BassClientServiceBinderTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -36,21 +36,24 @@ import android.bluetooth.IBluetoothLeBroadcastAssistantCallback;
import android.bluetooth.le.ScanFilter;
import android.content.AttributionSource;
+import androidx.test.filters.SmallTest;
import androidx.test.platform.app.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.junit.runners.JUnit4;
import org.mockito.Mock;
import org.mockito.Mockito;
import java.util.Collections;
import java.util.List;
-@RunWith(JUnit4.class)
-public class BleBroadcastAssistantBinderTest {
+/** Test cases for {@link BassClientServiceBinder} */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class BassClientServiceBinderTest {
@Rule public final MockitoRule mMockitoRule = new MockitoRule();
@@ -64,17 +67,16 @@ public class BleBroadcastAssistantBinderTest {
@Mock private BassClientService mService;
- private BassClientService.BluetoothLeBroadcastAssistantBinder mBinder;
+ private BassClientServiceBinder mBinder;
@Before
public void setUp() {
- mBinder = new BassClientService.BluetoothLeBroadcastAssistantBinder(mService);
+ mBinder = new BassClientServiceBinder(mService);
}
@Test
public void cleanUp() {
mBinder.cleanup();
- assertThat(mBinder.mService).isNull();
}
@Test
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 6b6d82827c..464cb5c652 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
@@ -1535,38 +1535,44 @@ public class BassClientServiceTest {
}
private void injectRemoteSourceStateChanged(
+ BassClientStateMachine sm,
+ BluetoothLeBroadcastMetadata meta,
+ boolean isPaSynced,
+ boolean isBisSynced) {
+ // Update receiver state
+ if (sm.getDevice().equals(mCurrentDevice)) {
+ injectRemoteSourceStateChanged(
+ sm,
+ meta,
+ TEST_SOURCE_ID,
+ isPaSynced
+ ? BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_SYNCHRONIZED
+ : BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE,
+ meta.isEncrypted()
+ ? BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING
+ : BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED,
+ null,
+ isBisSynced ? (long) 0x00000001 : (long) 0x00000000);
+ } else if (sm.getDevice().equals(mCurrentDevice1)) {
+ injectRemoteSourceStateChanged(
+ sm,
+ meta,
+ TEST_SOURCE_ID + 1,
+ isPaSynced
+ ? BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_SYNCHRONIZED
+ : BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE,
+ meta.isEncrypted()
+ ? BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING
+ : BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED,
+ null,
+ isBisSynced ? (long) 0x00000002 : (long) 0x00000000);
+ }
+ }
+
+ private void injectRemoteSourceStateChanged(
BluetoothLeBroadcastMetadata meta, boolean isPaSynced, boolean isBisSynced) {
for (BassClientStateMachine sm : mStateMachines.values()) {
- // Update receiver state
- if (sm.getDevice().equals(mCurrentDevice)) {
- injectRemoteSourceStateChanged(
- sm,
- meta,
- TEST_SOURCE_ID,
- isPaSynced
- ? BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_SYNCHRONIZED
- : BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE,
- meta.isEncrypted()
- ? BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING
- : BluetoothLeBroadcastReceiveState
- .BIG_ENCRYPTION_STATE_NOT_ENCRYPTED,
- null,
- isBisSynced ? (long) 0x00000001 : (long) 0x00000000);
- } else if (sm.getDevice().equals(mCurrentDevice1)) {
- injectRemoteSourceStateChanged(
- sm,
- meta,
- TEST_SOURCE_ID + 1,
- isPaSynced
- ? BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_SYNCHRONIZED
- : BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE,
- meta.isEncrypted()
- ? BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING
- : BluetoothLeBroadcastReceiveState
- .BIG_ENCRYPTION_STATE_NOT_ENCRYPTED,
- null,
- isBisSynced ? (long) 0x00000002 : (long) 0x00000000);
- }
+ injectRemoteSourceStateChanged(sm, meta, isPaSynced, isBisSynced);
}
}
@@ -1920,6 +1926,29 @@ public class BassClientServiceTest {
}
}
+ private void verifyModifyMessageAndInjectSourceModfified() {
+ for (BassClientStateMachine sm : mStateMachines.values()) {
+ ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
+ verify(sm, atLeast(1)).sendMessage(messageCaptor.capture());
+
+ Optional<Message> msg =
+ messageCaptor.getAllValues().stream()
+ .filter(m -> m.what == BassClientStateMachine.UPDATE_BCAST_SOURCE)
+ .findFirst();
+ assertThat(msg.isPresent()).isEqualTo(true);
+
+ if (sm.getDevice().equals(mCurrentDevice)) {
+ assertThat(msg.get().arg1).isEqualTo(TEST_SOURCE_ID);
+ injectRemoteSourceStateChanged(
+ sm, createBroadcastMetadata(TEST_BROADCAST_ID), false, false);
+ } else if (sm.getDevice().equals(mCurrentDevice1)) {
+ assertThat(msg.get().arg1).isEqualTo(TEST_SOURCE_ID + 1);
+ injectRemoteSourceStateChanged(
+ sm, createBroadcastMetadata(TEST_BROADCAST_ID), false, false);
+ }
+ }
+ }
+
/**
* Test whether service.removeSource() does send modify source if source is from remote receive
* state. In this case, assistant should be able to remove source which was not managed by BASS
@@ -4128,27 +4157,20 @@ public class BassClientServiceTest {
3 /* STATUS_LOCAL_STREAM_REQUESTED_NO_CONTEXT_VALIDATE */);
/* Imitate broadcast source stop, sink notify about loosing BIS sync */
- verifyRemoveMessageAndInjectSourceRemoval();
+ verifyModifyMessageAndInjectSourceModfified();
assertThat(mStateMachines).hasSize(2);
for (BassClientStateMachine sm : mStateMachines.values()) {
Mockito.clearInvocations(sm);
}
// Make another stream request with no context validate
- // and verify sm didn't get REMOVE_BCAST_SOURCE
mBassClientService.handleUnicastSourceStreamStatusChange(
3 /* STATUS_LOCAL_STREAM_REQUESTED_NO_CONTEXT_VALIDATE */);
// Make another stream request
- // and verify sinks to resume remain unchanged later
mBassClientService.handleUnicastSourceStreamStatusChange(
0 /* STATUS_LOCAL_STREAM_REQUESTED */);
- assertThat(mStateMachines).hasSize(2);
- for (BassClientStateMachine sm : mStateMachines.values()) {
- verify(sm, never()).sendMessage(any());
- }
-
/* Unicast finished streaming */
mBassClientService.handleUnicastSourceStreamStatusChange(
2 /* STATUS_LOCAL_STREAM_SUSPENDED */);
@@ -4162,7 +4184,7 @@ public class BassClientServiceTest {
messageCaptor.getAllValues().stream()
.filter(
m ->
- (m.what == BassClientStateMachine.ADD_BCAST_SOURCE)
+ (m.what == BassClientStateMachine.UPDATE_BCAST_SOURCE)
&& (m.obj == meta))
.findFirst()
.orElse(null);
@@ -5645,7 +5667,7 @@ public class BassClientServiceTest {
// Suspend receivers, HOST_INTENTIONAL
mBassClientService.suspendReceiversSourceSynchronization(TEST_BROADCAST_ID);
verifyStopBigMonitoringWithUnsync();
- verifyRemoveMessageAndInjectSourceRemoval();
+ verifyModifyMessageAndInjectSourceModfified();
checkNoResumeSynchronizationByBig();
checkResumeSynchronizationByHost();
}
@@ -5658,7 +5680,7 @@ public class BassClientServiceTest {
// Suspend receivers, HOST_INTENTIONAL
mBassClientService.suspendReceiversSourceSynchronization(TEST_BROADCAST_ID);
verifyStopBigMonitoringWithoutUnsync();
- verifyRemoveMessageAndInjectSourceRemoval();
+ verifyModifyMessageAndInjectSourceModfified();
checkNoResumeSynchronizationByBig();
checkResumeSynchronizationByHost();
}
@@ -5671,7 +5693,7 @@ public class BassClientServiceTest {
// Suspend all receivers, HOST_INTENTIONAL
mBassClientService.suspendAllReceiversSourceSynchronization();
verifyStopBigMonitoringWithUnsync();
- verifyRemoveMessageAndInjectSourceRemoval();
+ verifyModifyMessageAndInjectSourceModfified();
checkNoResumeSynchronizationByBig();
checkResumeSynchronizationByHost();
}
@@ -5684,7 +5706,7 @@ public class BassClientServiceTest {
// Suspend all receivers, HOST_INTENTIONAL
mBassClientService.suspendAllReceiversSourceSynchronization();
verifyStopBigMonitoringWithoutUnsync();
- verifyRemoveMessageAndInjectSourceRemoval();
+ verifyModifyMessageAndInjectSourceModfified();
checkNoResumeSynchronizationByBig();
checkResumeSynchronizationByHost();
}
@@ -5965,7 +5987,7 @@ public class BassClientServiceTest {
mBassClientService.handleUnicastSourceStreamStatusChange(
3 /* STATUS_LOCAL_STREAM_REQUESTED_NO_CONTEXT_VALIDATE */);
verifyStopBigMonitoringWithUnsync();
- verifyRemoveMessageAndInjectSourceRemoval();
+ verifyModifyMessageAndInjectSourceModfified();
checkNoResumeSynchronizationByBig();
/* Unicast finished streaming */
@@ -5984,7 +6006,7 @@ public class BassClientServiceTest {
mBassClientService.handleUnicastSourceStreamStatusChange(
3 /* STATUS_LOCAL_STREAM_REQUESTED_NO_CONTEXT_VALIDATE */);
verifyStopBigMonitoringWithoutUnsync();
- verifyRemoveMessageAndInjectSourceRemoval();
+ verifyModifyMessageAndInjectSourceModfified();
checkNoResumeSynchronizationByBig();
/* Unicast finished streaming */
@@ -6601,7 +6623,7 @@ public class BassClientServiceTest {
// Suspend all receivers, HOST_INTENTIONAL
mBassClientService.suspendAllReceiversSourceSynchronization();
- verifyRemoveMessageAndInjectSourceRemoval();
+ verifyModifyMessageAndInjectSourceModfified();
// Start searching sources sync to paused broadcaster and remain cache
startSearchingForSources();
@@ -6848,7 +6870,7 @@ public class BassClientServiceTest {
mBassClientService.handleUnicastSourceStreamStatusChange(
3 /* STATUS_LOCAL_STREAM_REQUESTED_NO_CONTEXT_VALIDATE */);
checkNoSinkPause();
- verifyRemoveMessageAndInjectSourceRemoval();
+ verifyModifyMessageAndInjectSourceModfified();
/* Unicast finished streaming */
mBassClientService.handleUnicastSourceStreamStatusChange(
@@ -6866,7 +6888,7 @@ public class BassClientServiceTest {
mBassClientService.handleUnicastSourceStreamStatusChange(
3 /* STATUS_LOCAL_STREAM_REQUESTED_NO_CONTEXT_VALIDATE */);
checkNoSinkPause();
- verifyRemoveMessageAndInjectSourceRemoval();
+ verifyModifyMessageAndInjectSourceModfified();
/* Unicast finished streaming */
mBassClientService.handleUnicastSourceStreamStatusChange(
@@ -7547,7 +7569,7 @@ public class BassClientServiceTest {
/* Unicast would like to stream */
mBassClientService.handleUnicastSourceStreamStatusChange(
3 /* STATUS_LOCAL_STREAM_REQUESTED_NO_CONTEXT_VALIDATE */);
- verifyRemoveMessageAndInjectSourceRemoval();
+ verifyModifyMessageAndInjectSourceModfified();
for (BassClientStateMachine sm : mStateMachines.values()) {
clearInvocations(sm);
}
@@ -7716,7 +7738,7 @@ public class BassClientServiceTest {
/* Unicast would like to stream */
mBassClientService.handleUnicastSourceStreamStatusChange(
3 /* STATUS_LOCAL_STREAM_REQUESTED_NO_CONTEXT_VALIDATE */);
- verifyRemoveMessageAndInjectSourceRemoval();
+ verifyModifyMessageAndInjectSourceModfified();
for (BassClientStateMachine sm : mStateMachines.values()) {
clearInvocations(sm);
}
@@ -7744,7 +7766,7 @@ public class BassClientServiceTest {
/* Unicast would like to stream */
mBassClientService.handleUnicastSourceStreamStatusChange(
3 /* STATUS_LOCAL_STREAM_REQUESTED_NO_CONTEXT_VALIDATE */);
- verifyRemoveMessageAndInjectSourceRemoval();
+ verifyModifyMessageAndInjectSourceModfified();
for (BassClientStateMachine sm : mStateMachines.values()) {
clearInvocations(sm);
}
@@ -7840,7 +7862,7 @@ public class BassClientServiceTest {
/* Unicast would like to stream */
mBassClientService.handleUnicastSourceStreamStatusChange(
3 /* STATUS_LOCAL_STREAM_REQUESTED_NO_CONTEXT_VALIDATE */);
- verifyRemoveMessageAndInjectSourceRemoval();
+ verifyModifyMessageAndInjectSourceModfified();
for (BassClientStateMachine sm : mStateMachines.values()) {
clearInvocations(sm);
}
diff --git a/android/app/tests/unit/src/com/android/bluetooth/bass_client/BassClientStateMachineTest.java b/android/app/tests/unit/src/com/android/bluetooth/bass_client/BassClientStateMachineTest.java
index 4f75fed146..6915785794 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/bass_client/BassClientStateMachineTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/bass_client/BassClientStateMachineTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -1213,7 +1213,7 @@ public class BassClientStateMachineTest {
// Update value - PA SyncInfo Request, local broadcast
mBassClientStateMachine.mPendingMetadata = createBroadcastMetadata();
- when(mBassClientService.isLocalBroadcast(any(BluetoothLeBroadcastMetadata.class)))
+ when(mBassClientService.isLocalBroadcast(any(BluetoothLeBroadcastReceiveState.class)))
.thenReturn(true);
cb.onCharacteristicChanged(null, characteristic);
TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper());
diff --git a/android/app/tests/unit/src/com/android/bluetooth/bass_client/PeriodicAdvertisementResultTest.java b/android/app/tests/unit/src/com/android/bluetooth/bass_client/PeriodicAdvertisementResultTest.java
index e86952a165..d7d0605fb5 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/bass_client/PeriodicAdvertisementResultTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/bass_client/PeriodicAdvertisementResultTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 The Android Open Source Project
+ * Copyright (C) 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/bass_client/PublicBroadcastDataTest.java b/android/app/tests/unit/src/com/android/bluetooth/bass_client/PublicBroadcastDataTest.java
index f8d3db6482..48c2b7935c 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/bass_client/PublicBroadcastDataTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/bass_client/PublicBroadcastDataTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 The Android Open Source Project
+ * Copyright (C) 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.
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 13f38272e6..2af03df4ae 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 The Android Open Source Project
+ * Copyright (C) 2018 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.
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 3e6180f336..db3a61cb3a 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 The Android Open Source Project
+ * Copyright (C) 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.
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 8c666babfd..7e143a2851 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 The Android Open Source Project
+ * Copyright (C) 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.
@@ -23,42 +23,50 @@ import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.IBluetoothOobDataCallback;
import android.content.AttributionSource;
import android.os.ParcelUuid;
+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.Mockito;
import java.io.FileDescriptor;
+/** Test cases for {@link AdapterServiceBinder} */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
public class AdapterServiceBinderTest {
@Rule public final MockitoRule mMockitoRule = new MockitoRule();
@Mock private AdapterService mService;
@Mock private AdapterProperties mAdapterProperties;
- private AdapterService.AdapterServiceBinder mBinder;
+ private AdapterServiceBinder mBinder;
private AttributionSource mAttributionSource;
@Before
public void setUp() {
- mService.mAdapterProperties = mAdapterProperties;
+ when(mService.getAdapterProperties()).thenReturn(mAdapterProperties);
doReturn(true).when(mService).isAvailable();
doNothing().when(mService).enforceCallingOrSelfPermission(any(), any());
- mBinder = new AdapterService.AdapterServiceBinder(mService);
+ mBinder = new AdapterServiceBinder(mService);
mAttributionSource = new AttributionSource.Builder(0).build();
}
@Test
public void getAddress() {
mBinder.getAddress(mAttributionSource);
- verify(mService.mAdapterProperties).getAddress();
+ verify(mAdapterProperties).getAddress();
}
@Test
@@ -116,7 +124,7 @@ public class AdapterServiceBinderTest {
@Test
public void isActivityAndEnergyReportingSupported() {
mBinder.isActivityAndEnergyReportingSupported();
- verify(mService.mAdapterProperties).isActivityAndEnergyReportingSupported();
+ verify(mAdapterProperties).isActivityAndEnergyReportingSupported();
}
@Test
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 4e510e75a0..a9e01b3086 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2017 The Android Open Source Project
+ * Copyright (C) 2017 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.
@@ -113,6 +113,7 @@ import java.util.Map;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
+/** Test cases for {@link AdapterService}. */
@MediumTest
@RunWith(ParameterizedAndroidJunit4.class)
public class AdapterServiceTest {
diff --git a/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterSuspendTest.java b/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterSuspendTest.java
index c175cfaa02..bc86ce8ee1 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterSuspendTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterSuspendTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 The Android Open Source Project
+ * Copyright (C) 2024 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.
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 044ededd4a..f420ffb43f 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 The Android Open Source Project
+ * Copyright (C) 2018 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.
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 2b3d692035..bea6e8ea6d 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/btservice/ConfigTest.java b/android/app/tests/unit/src/com/android/bluetooth/btservice/ConfigTest.java
index de1c706db2..704234cf1e 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/btservice/ConfigTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/btservice/ConfigTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 The Android Open Source Project
+ * Copyright (C) 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.
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 21f04ff490..ae3db21382 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 The Android Open Source Project
+ * Copyright (C) 2018 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.
@@ -20,15 +20,24 @@ import static com.android.bluetooth.TestUtils.getTestDevice;
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
import android.bluetooth.BluetoothDevice;
+import android.content.ContentResolver;
+import android.provider.Settings;
+import androidx.test.core.app.ApplicationProvider;
import androidx.test.filters.MediumTest;
import androidx.test.runner.AndroidJUnit4;
-import com.android.bluetooth.BluetoothMetricsProto.BluetoothLog;
import com.android.bluetooth.BluetoothMetricsProto.BluetoothRemoteDeviceInformation;
-import com.android.bluetooth.BluetoothMetricsProto.ProfileConnectionStats;
-import com.android.bluetooth.BluetoothMetricsProto.ProfileId;
+import com.android.bluetooth.BluetoothStatsLog;
import com.google.common.hash.BloomFilter;
import com.google.common.hash.Funnels;
@@ -40,11 +49,13 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
+import org.mockito.Mockito;
import java.io.ByteArrayInputStream;
import java.io.IOException;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
import java.util.HashMap;
-import java.util.List;
import java.util.Map;
/** Unit tests for {@link MetricsLogger} */
@@ -111,68 +122,15 @@ public class MetricsLoggerTest {
@Before
public void setUp() {
- MetricsLogger.dumpProto(BluetoothLog.newBuilder());
mTestableMetricsLogger = new TestableMetricsLogger();
mTestableMetricsLogger.init(mAdapterService, mRemoteDevices);
}
@After
public void tearDown() {
- // Dump metrics to clean up internal states
- MetricsLogger.dumpProto(BluetoothLog.newBuilder());
mTestableMetricsLogger.close();
}
- /** Simple test to verify that profile connection event can be logged, dumped, and cleaned */
- @Test
- public void testLogProfileConnectionEvent() {
- MetricsLogger.logProfileConnectionEvent(ProfileId.AVRCP);
- BluetoothLog.Builder metricsBuilder = BluetoothLog.newBuilder();
- MetricsLogger.dumpProto(metricsBuilder);
- BluetoothLog metricsProto = metricsBuilder.build();
- assertThat(metricsProto.getProfileConnectionStatsCount()).isEqualTo(1);
- ProfileConnectionStats profileUsageStatsAvrcp = metricsProto.getProfileConnectionStats(0);
- assertThat(profileUsageStatsAvrcp.getProfileId()).isEqualTo(ProfileId.AVRCP);
- assertThat(profileUsageStatsAvrcp.getNumTimesConnected()).isEqualTo(1);
- // Verify that MetricsLogger's internal state is cleared after a dump
- BluetoothLog.Builder metricsBuilderAfterDump = BluetoothLog.newBuilder();
- MetricsLogger.dumpProto(metricsBuilderAfterDump);
- BluetoothLog metricsProtoAfterDump = metricsBuilderAfterDump.build();
- assertThat(metricsProtoAfterDump.getProfileConnectionStatsCount()).isEqualTo(0);
- }
-
- /** Test whether multiple profile's connection events can be logged interleaving */
- @Test
- public void testLogProfileConnectionEventMultipleProfile() {
- MetricsLogger.logProfileConnectionEvent(ProfileId.AVRCP);
- MetricsLogger.logProfileConnectionEvent(ProfileId.HEADSET);
- MetricsLogger.logProfileConnectionEvent(ProfileId.AVRCP);
- BluetoothLog.Builder metricsBuilder = BluetoothLog.newBuilder();
- MetricsLogger.dumpProto(metricsBuilder);
- BluetoothLog metricsProto = metricsBuilder.build();
- assertThat(metricsProto.getProfileConnectionStatsCount()).isEqualTo(2);
- Map<ProfileId, ProfileConnectionStats> profileConnectionCountMap =
- getProfileUsageStatsMap(metricsProto.getProfileConnectionStatsList());
- assertThat(profileConnectionCountMap).containsKey(ProfileId.AVRCP);
- assertThat(profileConnectionCountMap.get(ProfileId.AVRCP).getNumTimesConnected())
- .isEqualTo(2);
- assertThat(profileConnectionCountMap).containsKey(ProfileId.HEADSET);
- assertThat(profileConnectionCountMap.get(ProfileId.HEADSET).getNumTimesConnected())
- .isEqualTo(1);
- // Verify that MetricsLogger's internal state is cleared after a dump
- BluetoothLog.Builder metricsBuilderAfterDump = BluetoothLog.newBuilder();
- MetricsLogger.dumpProto(metricsBuilderAfterDump);
- BluetoothLog metricsProtoAfterDump = metricsBuilderAfterDump.build();
- assertThat(metricsProtoAfterDump.getProfileConnectionStatsCount()).isEqualTo(0);
- }
-
- private static Map<ProfileId, ProfileConnectionStats> getProfileUsageStatsMap(
- List<ProfileConnectionStats> profileUsageStats) {
- HashMap<ProfileId, ProfileConnectionStats> profileUsageStatsMap = new HashMap<>();
- profileUsageStats.forEach(item -> profileUsageStatsMap.put(item.getProfileId(), item));
- return profileUsageStatsMap;
- }
-
/** Test add counters and send them to statsd */
@Test
public void testAddAndSendCountersNormalCases() {
@@ -293,6 +251,51 @@ public class MetricsLoggerTest {
assertThat(mTestableMetricsLogger.logAllowlistedDeviceNameHash(1, "")).isEmpty();
}
+ @Test
+ public void testUpdateHearingDeviceActiveTime() {
+ BluetoothDevice bluetoothDevice = getTestDevice(0);
+ int day = BluetoothStatsLog.HEARING_DEVICE_ACTIVE_EVENT_REPORTED__TIME_PERIOD__DAY;
+ int week = BluetoothStatsLog.HEARING_DEVICE_ACTIVE_EVENT_REPORTED__TIME_PERIOD__WEEK;
+ int month = BluetoothStatsLog.HEARING_DEVICE_ACTIVE_EVENT_REPORTED__TIME_PERIOD__MONTH;
+ doReturn(ApplicationProvider.getApplicationContext().getContentResolver())
+ .when(mAdapterService)
+ .getContentResolver();
+
+ // last active time is 2 days ago, should update last active day
+ TestableMetricsLogger logger = spy(mTestableMetricsLogger);
+ prepareLastActiveTimeDaysAgo(2);
+ logger.updateHearingDeviceActiveTime(bluetoothDevice, 1);
+ verify(logger).logHearingDeviceActiveEvent(any(), anyInt(), eq(day));
+ verify(logger, never()).logHearingDeviceActiveEvent(any(), anyInt(), eq(week));
+ verify(logger, never()).logHearingDeviceActiveEvent(any(), anyInt(), eq(month));
+
+ // last active time is 8 days ago, should update last active day and week
+ Mockito.reset(logger);
+ prepareLastActiveTimeDaysAgo(8);
+ logger.updateHearingDeviceActiveTime(bluetoothDevice, 1);
+ verify(logger).logHearingDeviceActiveEvent(any(), anyInt(), eq(day));
+ verify(logger).logHearingDeviceActiveEvent(any(), anyInt(), eq(week));
+ verify(logger, never()).logHearingDeviceActiveEvent(any(), anyInt(), eq(month));
+
+ // last active time is 60 days ago, should update last active day, week and month
+ Mockito.reset(logger);
+ prepareLastActiveTimeDaysAgo(60);
+ logger.updateHearingDeviceActiveTime(bluetoothDevice, 1);
+ verify(logger).logHearingDeviceActiveEvent(any(), anyInt(), eq(day));
+ verify(logger).logHearingDeviceActiveEvent(any(), anyInt(), eq(week));
+ verify(logger).logHearingDeviceActiveEvent(any(), anyInt(), eq(month));
+ }
+
+ private static void prepareLastActiveTimeDaysAgo(int days) {
+ final ContentResolver contentResolver =
+ ApplicationProvider.getApplicationContext().getContentResolver();
+ final LocalDateTime now = LocalDateTime.now(ZoneId.systemDefault());
+ final String lastActive = now.minusDays(days).toString();
+ Settings.Secure.putString(contentResolver, "last_active_day", lastActive);
+ Settings.Secure.putString(contentResolver, "last_active_week", lastActive);
+ Settings.Secure.putString(contentResolver, "last_active_month", lastActive);
+ }
+
private void initTestingBloomfilter() throws IOException {
byte[] bloomfilterData =
DeviceBloomfilterGenerator.hexStringToByteArray(
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 dd7d46d661..960374ddae 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 The Android Open Source Project
+ * Copyright (C) 2018 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.
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 75e3eac68e..8cbf61d8d8 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
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 e44682c266..0b3cc08343 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/btservice/storage/AudioPolicyEntityTest.java b/android/app/tests/unit/src/com/android/bluetooth/btservice/storage/AudioPolicyEntityTest.java
index 38dd6d6807..317153b64b 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/btservice/storage/AudioPolicyEntityTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/btservice/storage/AudioPolicyEntityTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 The Android Open Source Project
+ * Copyright (C) 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.
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 b020dbf6d8..21449beaf5 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
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 dc4e6dc5e8..e682e9af17 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 The Android Open Source Project
+ * Copyright (C) 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/csip/BluetoothCsisBinderTest.java b/android/app/tests/unit/src/com/android/bluetooth/csip/CsipSetCoordinatorServiceBinderTest.java
index 69e8546ac3..81adae18f4 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/csip/BluetoothCsisBinderTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/csip/CsipSetCoordinatorServiceBinderTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -30,12 +30,20 @@ import android.bluetooth.IBluetoothCsipSetCoordinatorLockCallback;
import android.content.AttributionSource;
import android.os.ParcelUuid;
+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;
-public class BluetoothCsisBinderTest {
+/** Test cases for {@link CsipSetCoordinatorServiceBinder} */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class CsipSetCoordinatorServiceBinderTest {
+
@Rule public final MockitoRule mMockitoRule = new MockitoRule();
@Mock private CsipSetCoordinatorService mService;
@@ -43,11 +51,11 @@ public class BluetoothCsisBinderTest {
private final BluetoothDevice mDevice = getTestDevice(45);
private final AttributionSource mAttributionSource = new AttributionSource.Builder(1).build();
- private CsipSetCoordinatorService.BluetoothCsisBinder mBinder;
+ private CsipSetCoordinatorServiceBinder mBinder;
@Before
public void setUp() throws Exception {
- mBinder = new CsipSetCoordinatorService.BluetoothCsisBinder(mService);
+ mBinder = new CsipSetCoordinatorServiceBinder(mService);
}
@Test
@@ -59,6 +67,7 @@ public class BluetoothCsisBinderTest {
@Test
public void getDevicesMatchingConnectionStates() {
int[] states = new int[] {STATE_CONNECTED};
+
mBinder.getDevicesMatchingConnectionStates(states, mAttributionSource);
verify(mService).getDevicesMatchingConnectionStates(states);
}
@@ -72,6 +81,7 @@ public class BluetoothCsisBinderTest {
@Test
public void setConnectionPolicy() {
int connectionPolicy = CONNECTION_POLICY_ALLOWED;
+
mBinder.setConnectionPolicy(mDevice, connectionPolicy, mAttributionSource);
verify(mService).setConnectionPolicy(mDevice, connectionPolicy);
}
@@ -87,6 +97,7 @@ public class BluetoothCsisBinderTest {
int groupId = 100;
IBluetoothCsipSetCoordinatorLockCallback cb =
mock(IBluetoothCsipSetCoordinatorLockCallback.class);
+
mBinder.lockGroup(groupId, cb, mAttributionSource);
verify(mService).lockGroup(groupId, cb);
}
@@ -94,6 +105,7 @@ public class BluetoothCsisBinderTest {
@Test
public void unlockGroup() {
ParcelUuid uuid = ParcelUuid.fromString("0000110A-0000-1000-8000-00805F9B34FB");
+
mBinder.unlockGroup(uuid, mAttributionSource);
verify(mService).unlockGroup(uuid.getUuid());
}
@@ -101,6 +113,7 @@ public class BluetoothCsisBinderTest {
@Test
public void getAllGroupIds() {
ParcelUuid uuid = ParcelUuid.fromString("0000110A-0000-1000-8000-00805F9B34FB");
+
mBinder.getAllGroupIds(uuid, mAttributionSource);
verify(mService).getAllGroupIds(uuid);
}
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 ac64b097ae..72fbd125b6 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
@@ -130,7 +130,6 @@ public class CsipSetCoordinatorServiceTest {
new CsipSetCoordinatorService(
mAdapterService, mLooper.getLooper(), mNativeInterface, mServiceFactory);
mService.setAvailable(true);
-
}
@After
diff --git a/android/app/tests/unit/src/com/android/bluetooth/gatt/AdvertiseBinderTest.java b/android/app/tests/unit/src/com/android/bluetooth/gatt/AdvertiseBinderTest.java
deleted file mode 100644
index f90223cd24..0000000000
--- a/android/app/tests/unit/src/com/android/bluetooth/gatt/AdvertiseBinderTest.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * Copyright 2025 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.bluetooth.gatt;
-
-import static com.android.bluetooth.TestUtils.MockitoRule;
-
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
-import android.bluetooth.BluetoothManager;
-import android.bluetooth.le.AdvertiseData;
-import android.bluetooth.le.AdvertisingSetParameters;
-import android.bluetooth.le.IAdvertisingSetCallback;
-import android.bluetooth.le.PeriodicAdvertisingParameters;
-import android.content.AttributionSource;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.platform.app.InstrumentationRegistry;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.bluetooth.btservice.AdapterService;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-
-/** Test cases for {@link AdvertiseBinder}. */
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class AdvertiseBinderTest {
- @Rule public final MockitoRule mMockitoRule = new MockitoRule();
-
- @Mock private AdapterService mAdapterService;
- @Mock private AdvertiseManager mAdvertiseManager;
-
- private final AttributionSource mAttributionSource =
- InstrumentationRegistry.getInstrumentation()
- .getTargetContext()
- .getSystemService(BluetoothManager.class)
- .getAdapter()
- .getAttributionSource();
- private AdvertiseBinder mBinder;
-
- @Before
- public void setUp() {
- doAnswer(
- invocation -> {
- ((Runnable) invocation.getArgument(0)).run();
- return null;
- })
- .when(mAdvertiseManager)
- .doOnAdvertiseThread(any());
- mBinder = new AdvertiseBinder(mAdapterService, mAdvertiseManager);
- }
-
- @Test
- public void startAdvertisingSet() {
- AdvertisingSetParameters parameters = new AdvertisingSetParameters.Builder().build();
- AdvertiseData advertiseData = new AdvertiseData.Builder().build();
- AdvertiseData scanResponse = new AdvertiseData.Builder().build();
- PeriodicAdvertisingParameters periodicParameters =
- new PeriodicAdvertisingParameters.Builder().build();
- AdvertiseData periodicData = new AdvertiseData.Builder().build();
- int duration = 1;
- int maxExtAdvEvents = 2;
- int serverIf = 3;
- IAdvertisingSetCallback callback = mock(IAdvertisingSetCallback.class);
-
- mBinder.startAdvertisingSet(
- parameters,
- advertiseData,
- scanResponse,
- periodicParameters,
- periodicData,
- duration,
- maxExtAdvEvents,
- serverIf,
- callback,
- mAttributionSource);
-
- verify(mAdvertiseManager)
- .startAdvertisingSet(
- parameters,
- advertiseData,
- scanResponse,
- periodicParameters,
- periodicData,
- duration,
- maxExtAdvEvents,
- serverIf,
- callback,
- mAttributionSource);
- }
-
- @Test
- public void stopAdvertisingSet() {
- IAdvertisingSetCallback callback = mock(IAdvertisingSetCallback.class);
-
- mBinder.stopAdvertisingSet(callback, mAttributionSource);
-
- verify(mAdvertiseManager).stopAdvertisingSet(callback);
- }
-
- @Test
- public void setAdvertisingData() {
- int advertiserId = 1;
- AdvertiseData data = new AdvertiseData.Builder().build();
-
- mBinder.setAdvertisingData(advertiserId, data, mAttributionSource);
- verify(mAdvertiseManager).setAdvertisingData(advertiserId, data);
- }
-
- @Test
- public void setAdvertisingParameters() {
- int advertiserId = 1;
- AdvertisingSetParameters parameters = new AdvertisingSetParameters.Builder().build();
-
- mBinder.setAdvertisingParameters(advertiserId, parameters, mAttributionSource);
- verify(mAdvertiseManager).setAdvertisingParameters(advertiserId, parameters);
- }
-
- @Test
- public void setPeriodicAdvertisingData() {
- int advertiserId = 1;
- AdvertiseData data = new AdvertiseData.Builder().build();
-
- mBinder.setPeriodicAdvertisingData(advertiserId, data, mAttributionSource);
- verify(mAdvertiseManager).setPeriodicAdvertisingData(advertiserId, data);
- }
-
- @Test
- public void setPeriodicAdvertisingEnable() {
- int advertiserId = 1;
- boolean enable = true;
-
- mBinder.setPeriodicAdvertisingEnable(advertiserId, enable, mAttributionSource);
- verify(mAdvertiseManager).setPeriodicAdvertisingEnable(advertiserId, enable);
- }
-
- @Test
- public void setPeriodicAdvertisingParameters() {
- int advertiserId = 1;
- PeriodicAdvertisingParameters parameters =
- new PeriodicAdvertisingParameters.Builder().build();
-
- mBinder.setPeriodicAdvertisingParameters(advertiserId, parameters, mAttributionSource);
- verify(mAdvertiseManager).setPeriodicAdvertisingParameters(advertiserId, parameters);
- }
-
- @Test
- public void setScanResponseData() {
- int advertiserId = 1;
- AdvertiseData data = new AdvertiseData.Builder().build();
-
- mBinder.setScanResponseData(advertiserId, data, mAttributionSource);
- verify(mAdvertiseManager).setScanResponseData(advertiserId, data);
- }
-
- @Test
- public void getOwnAddress() {
- int advertiserId = 1;
-
- mBinder.getOwnAddress(advertiserId, mAttributionSource);
- verify(mAdvertiseManager).getOwnAddress(advertiserId);
- }
-
- @Test
- public void enableAdvertisingSet() {
- int advertiserId = 1;
- boolean enable = true;
- int duration = 3;
- int maxExtAdvEvents = 4;
-
- mBinder.enableAdvertisingSet(
- advertiserId, enable, duration, maxExtAdvEvents, mAttributionSource);
- verify(mAdvertiseManager)
- .enableAdvertisingSet(advertiserId, enable, duration, maxExtAdvEvents);
- }
-
- @Test
- public void cleanUp_doesNotCrash() {
- mBinder.cleanup();
- }
-}
diff --git a/android/app/tests/unit/src/com/android/bluetooth/gatt/AdvertiseBinderTest.kt b/android/app/tests/unit/src/com/android/bluetooth/gatt/AdvertiseBinderTest.kt
new file mode 100644
index 0000000000..6b038678f0
--- /dev/null
+++ b/android/app/tests/unit/src/com/android/bluetooth/gatt/AdvertiseBinderTest.kt
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.bluetooth.gatt
+
+import android.bluetooth.BluetoothManager
+import android.bluetooth.le.AdvertiseData
+import android.bluetooth.le.AdvertisingSetParameters
+import android.bluetooth.le.IAdvertisingSetCallback
+import android.bluetooth.le.PeriodicAdvertisingParameters
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import androidx.test.platform.app.InstrumentationRegistry
+import com.android.bluetooth.TestUtils.MockitoRule
+import com.android.bluetooth.btservice.AdapterService
+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.any
+import org.mockito.Mockito.doAnswer
+import org.mockito.Mockito.mock
+import org.mockito.Mockito.verify
+import org.mockito.kotlin.whenever
+
+/** Test cases for [AdvertiseBinder] */
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class AdvertiseBinderTest {
+
+ @get:Rule val mockitoRule = MockitoRule()
+
+ @Mock private lateinit var adapterService: AdapterService
+ @Mock private lateinit var advertiseManager: AdvertiseManager
+
+ private val attributionSource =
+ InstrumentationRegistry.getInstrumentation()
+ .targetContext
+ .getSystemService(BluetoothManager::class.java)
+ .adapter
+ .attributionSource
+
+ private lateinit var binder: AdvertiseBinder
+
+ @Before
+ fun setUp() {
+ doAnswer { invocation ->
+ (invocation.getArgument(0) as Runnable).run()
+ null
+ }
+ .whenever(advertiseManager)
+ .doOnAdvertiseThread(any())
+ binder = AdvertiseBinder(adapterService, advertiseManager)
+ }
+
+ @Test
+ fun startAdvertisingSet() {
+ val parameters = AdvertisingSetParameters.Builder().build()
+ val advertiseData = AdvertiseData.Builder().build()
+ val scanResponse = AdvertiseData.Builder().build()
+ val periodicParameters = PeriodicAdvertisingParameters.Builder().build()
+ val periodicData = AdvertiseData.Builder().build()
+ val duration = 1
+ val maxExtAdvEvents = 2
+ val serverIf = 3
+ val callback = mock(IAdvertisingSetCallback::class.java)
+
+ binder.startAdvertisingSet(
+ parameters,
+ advertiseData,
+ scanResponse,
+ periodicParameters,
+ periodicData,
+ duration,
+ maxExtAdvEvents,
+ serverIf,
+ callback,
+ attributionSource,
+ )
+ verify(advertiseManager)
+ .startAdvertisingSet(
+ parameters,
+ advertiseData,
+ scanResponse,
+ periodicParameters,
+ periodicData,
+ duration,
+ maxExtAdvEvents,
+ serverIf,
+ callback,
+ attributionSource,
+ )
+ }
+
+ @Test
+ fun stopAdvertisingSet() {
+ val callback = mock(IAdvertisingSetCallback::class.java)
+
+ binder.stopAdvertisingSet(callback, attributionSource)
+ verify(advertiseManager).stopAdvertisingSet(callback)
+ }
+
+ @Test
+ fun setAdvertisingData() {
+ val advertiserId = 1
+ val data = AdvertiseData.Builder().build()
+
+ binder.setAdvertisingData(advertiserId, data, attributionSource)
+ verify(advertiseManager).setAdvertisingData(advertiserId, data)
+ }
+
+ @Test
+ fun setAdvertisingParameters() {
+ val advertiserId = 1
+ val parameters = AdvertisingSetParameters.Builder().build()
+
+ binder.setAdvertisingParameters(advertiserId, parameters, attributionSource)
+ verify(advertiseManager).setAdvertisingParameters(advertiserId, parameters)
+ }
+
+ @Test
+ fun setPeriodicAdvertisingData() {
+ val advertiserId = 1
+ val data = AdvertiseData.Builder().build()
+
+ binder.setPeriodicAdvertisingData(advertiserId, data, attributionSource)
+ verify(advertiseManager).setPeriodicAdvertisingData(advertiserId, data)
+ }
+
+ @Test
+ fun setPeriodicAdvertisingEnable() {
+ val advertiserId = 1
+ val enable = true
+
+ binder.setPeriodicAdvertisingEnable(advertiserId, enable, attributionSource)
+ verify(advertiseManager).setPeriodicAdvertisingEnable(advertiserId, enable)
+ }
+
+ @Test
+ fun setPeriodicAdvertisingParameters() {
+ val advertiserId = 1
+ val parameters = PeriodicAdvertisingParameters.Builder().build()
+
+ binder.setPeriodicAdvertisingParameters(advertiserId, parameters, attributionSource)
+ verify(advertiseManager).setPeriodicAdvertisingParameters(advertiserId, parameters)
+ }
+
+ @Test
+ fun setScanResponseData() {
+ val advertiserId = 1
+ val data = AdvertiseData.Builder().build()
+
+ binder.setScanResponseData(advertiserId, data, attributionSource)
+ verify(advertiseManager).setScanResponseData(advertiserId, data)
+ }
+
+ @Test
+ fun getOwnAddress() {
+ val advertiserId = 1
+
+ binder.getOwnAddress(advertiserId, attributionSource)
+ verify(advertiseManager).getOwnAddress(advertiserId)
+ }
+
+ @Test
+ fun enableAdvertisingSet() {
+ val advertiserId = 1
+ val enable = true
+ val duration = 3
+ val maxExtAdvEvents = 4
+
+ binder.enableAdvertisingSet(
+ advertiserId,
+ enable,
+ duration,
+ maxExtAdvEvents,
+ attributionSource,
+ )
+ verify(advertiseManager)
+ .enableAdvertisingSet(advertiserId, enable, duration, maxExtAdvEvents)
+ }
+
+ @Test
+ fun cleanup_doesNotCrash() {
+ binder.cleanup()
+ }
+}
diff --git a/android/app/tests/unit/src/com/android/bluetooth/gatt/AdvertiseHelperTest.java b/android/app/tests/unit/src/com/android/bluetooth/gatt/AdvertiseHelperTest.java
index bf05afed39..6b461556fe 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/gatt/AdvertiseHelperTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/gatt/AdvertiseHelperTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
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 8537795af5..5aab3db081 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/gatt/AdvertiserMapTest.java b/android/app/tests/unit/src/com/android/bluetooth/gatt/AdvertiserMapTest.java
index df0d609e89..35d222f739 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/gatt/AdvertiserMapTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/gatt/AdvertiserMapTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 The Android Open Source Project
+ * Copyright (C) 2024 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.
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 42934127d5..e2bcfb75e2 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -305,7 +305,6 @@ public class AppAdvertiseStatsTest {
}
@Test
- @EnableFlags(Flags.FLAG_BLE_SCAN_ADV_METRICS_REDESIGN)
public void testAdvertiseCounterMetrics() {
int appUid = 0;
int id = 1;
@@ -356,7 +355,8 @@ public class AppAdvertiseStatsTest {
true,
instanceCount,
0,
- IMPORTANCE_FOREGROUND_SERVICE);
+ IMPORTANCE_FOREGROUND_SERVICE,
+ "");
Mockito.clearInvocations(mMetricsLogger);
// Wait for adv test duration
@@ -390,7 +390,8 @@ public class AppAdvertiseStatsTest {
eq(true),
eq(instanceCount),
mAdvDurationCaptor.capture(),
- eq(IMPORTANCE_FOREGROUND_SERVICE));
+ eq(IMPORTANCE_FOREGROUND_SERVICE),
+ eq(""));
long capturedAppScanDuration = mAdvDurationCaptor.getValue();
Log.d(TAG, "capturedDuration: " + capturedAppScanDuration);
assertThat(capturedAppScanDuration).isAtLeast(advTestDuration);
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 dac06a7086..6df604077d 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/gatt/DistanceMeasurementBinderTest.java b/android/app/tests/unit/src/com/android/bluetooth/gatt/DistanceMeasurementBinderTest.java
deleted file mode 100644
index 9db59f4fb1..0000000000
--- a/android/app/tests/unit/src/com/android/bluetooth/gatt/DistanceMeasurementBinderTest.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright 2025 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.bluetooth.gatt;
-
-import static com.android.bluetooth.TestUtils.MockitoRule;
-import static com.android.bluetooth.TestUtils.getTestDevice;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothManager;
-import android.bluetooth.le.DistanceMeasurementMethod;
-import android.bluetooth.le.DistanceMeasurementParams;
-import android.bluetooth.le.IDistanceMeasurementCallback;
-import android.content.AttributionSource;
-import android.os.ParcelUuid;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.platform.app.InstrumentationRegistry;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.bluetooth.btservice.AdapterService;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-
-import java.util.Collections;
-import java.util.UUID;
-
-/** Test cases for {@link DistanceMeasurementBinder}. */
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class DistanceMeasurementBinderTest {
- @Rule public final MockitoRule mMockitoRule = new MockitoRule();
-
- @Mock private DistanceMeasurementManager mDistanceMeasurementManager;
- @Mock private AdapterService mAdapterService;
-
- private final AttributionSource mAttributionSource =
- InstrumentationRegistry.getInstrumentation()
- .getTargetContext()
- .getSystemService(BluetoothManager.class)
- .getAdapter()
- .getAttributionSource();
-
- private DistanceMeasurementBinder mBinder;
-
- @Before
- public void setUp() throws Throwable {
- mBinder = new DistanceMeasurementBinder(mAdapterService, mDistanceMeasurementManager);
- when(mDistanceMeasurementManager.getSupportedDistanceMeasurementMethods())
- .thenReturn(Collections.emptyList());
- when(mDistanceMeasurementManager.runOnDistanceMeasurementThreadAndWaitForResult(any()))
- .thenAnswer(
- invocationOnMock -> {
- DistanceMeasurementManager.GetResultTask task =
- invocationOnMock.getArgument(0);
- return task.getResult();
- });
- doAnswer(
- invocation -> {
- ((Runnable) (invocation.getArgument(0))).run();
- return null;
- })
- .when(mDistanceMeasurementManager)
- .postOnDistanceMeasurementThread(any());
- }
-
- @Test
- public void getSupportedDistanceMeasurementMethods() {
- mBinder.getSupportedDistanceMeasurementMethods(mAttributionSource);
- verify(mDistanceMeasurementManager).getSupportedDistanceMeasurementMethods();
- }
-
- @Test
- public void startDistanceMeasurement() {
- UUID uuid = UUID.randomUUID();
- BluetoothDevice device = getTestDevice(3);
- DistanceMeasurementParams params =
- new DistanceMeasurementParams.Builder(device)
- .setDurationSeconds(123)
- .setFrequency(DistanceMeasurementParams.REPORT_FREQUENCY_LOW)
- .build();
- IDistanceMeasurementCallback callback = mock(IDistanceMeasurementCallback.class);
- mBinder.startDistanceMeasurement(
- new ParcelUuid(uuid), params, callback, mAttributionSource);
- verify(mDistanceMeasurementManager).startDistanceMeasurement(uuid, params, callback);
- }
-
- @Test
- public void stopDistanceMeasurement() {
- UUID uuid = UUID.randomUUID();
- BluetoothDevice device = getTestDevice(3);
- int method = DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI;
- mBinder.stopDistanceMeasurement(new ParcelUuid(uuid), device, method, mAttributionSource);
- verify(mDistanceMeasurementManager).stopDistanceMeasurement(uuid, device, method, false);
- }
-}
diff --git a/android/app/tests/unit/src/com/android/bluetooth/gatt/DistanceMeasurementBinderTest.kt b/android/app/tests/unit/src/com/android/bluetooth/gatt/DistanceMeasurementBinderTest.kt
new file mode 100644
index 0000000000..b20eda9a17
--- /dev/null
+++ b/android/app/tests/unit/src/com/android/bluetooth/gatt/DistanceMeasurementBinderTest.kt
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.bluetooth.gatt
+
+import android.bluetooth.BluetoothDevice
+import android.bluetooth.BluetoothManager
+import android.bluetooth.le.DistanceMeasurementMethod
+import android.bluetooth.le.DistanceMeasurementParams
+import android.bluetooth.le.IDistanceMeasurementCallback
+import android.os.ParcelUuid
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import androidx.test.platform.app.InstrumentationRegistry
+import com.android.bluetooth.TestUtils.MockitoRule
+import com.android.bluetooth.TestUtils.getTestDevice
+import com.android.bluetooth.btservice.AdapterService
+import com.android.bluetooth.gatt.DistanceMeasurementManager.GetResultTask
+import java.util.UUID
+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.any
+import org.mockito.Mockito.doAnswer
+import org.mockito.Mockito.doReturn
+import org.mockito.Mockito.mock
+import org.mockito.Mockito.verify
+import org.mockito.kotlin.whenever
+
+/** Test cases for [DistanceMeasurementBinder] */
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class DistanceMeasurementBinderTest {
+
+ @get:Rule val mockitoRule = MockitoRule()
+
+ @Mock private lateinit var distanceMeasurementManager: DistanceMeasurementManager
+ @Mock private lateinit var adapterService: AdapterService
+
+ private val attributionSource =
+ InstrumentationRegistry.getInstrumentation()
+ .targetContext
+ .getSystemService(BluetoothManager::class.java)
+ .adapter
+ .attributionSource
+
+ private lateinit var binder: DistanceMeasurementBinder
+
+ @Before
+ fun setUp() {
+ binder = DistanceMeasurementBinder(adapterService, distanceMeasurementManager)
+ doReturn(emptyList<DistanceMeasurementMethod>())
+ .whenever(distanceMeasurementManager)
+ .getSupportedDistanceMeasurementMethods()
+ doAnswer { invocationOnMock ->
+ val task = invocationOnMock.getArgument<GetResultTask<*>>(0)
+ task.result
+ }
+ .whenever(distanceMeasurementManager)
+ .runOnDistanceMeasurementThreadAndWaitForResult(any<GetResultTask<*>>())
+ doAnswer { invocation ->
+ (invocation.getArgument(0) as Runnable).run()
+ null
+ }
+ .whenever(distanceMeasurementManager)
+ .postOnDistanceMeasurementThread(any())
+ }
+
+ @Test
+ fun getSupportedDistanceMeasurementMethods() {
+ binder.getSupportedDistanceMeasurementMethods(attributionSource)
+ verify(distanceMeasurementManager).supportedDistanceMeasurementMethods
+ }
+
+ @Test
+ fun startDistanceMeasurement() {
+ val uuid = UUID.randomUUID()
+ val device: BluetoothDevice = getTestDevice(3)
+ val params =
+ DistanceMeasurementParams.Builder(device)
+ .setDurationSeconds(123)
+ .setFrequency(DistanceMeasurementParams.REPORT_FREQUENCY_LOW)
+ .build()
+ val callback = mock(IDistanceMeasurementCallback::class.java)
+ binder.startDistanceMeasurement(ParcelUuid(uuid), params, callback, attributionSource)
+ verify(distanceMeasurementManager).startDistanceMeasurement(uuid, params, callback)
+ }
+
+ @Test
+ fun stopDistanceMeasurement() {
+ val uuid = UUID.randomUUID()
+ val device: BluetoothDevice = getTestDevice(3)
+ val method = DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI
+ binder.stopDistanceMeasurement(ParcelUuid(uuid), device, method, attributionSource)
+ verify(distanceMeasurementManager).stopDistanceMeasurement(uuid, device, method, false)
+ }
+}
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 4237759122..8b4760c42f 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
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 a246d76b8f..f9bb1d556d 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -42,6 +42,7 @@ import org.mockito.Mock;
import java.util.UUID;
+/** Test cases for {@link GattServiceBinder} */
@SmallTest
@RunWith(AndroidJUnit4.class)
public class GattServiceBinderTest {
@@ -53,13 +54,12 @@ public class GattServiceBinderTest {
@Mock private GattService mService;
private AttributionSource mAttributionSource;
-
- private GattService.BluetoothGattBinder mBinder;
+ private GattServiceBinder mBinder;
@Before
public void setUp() throws Exception {
when(mService.isAvailable()).thenReturn(true);
- mBinder = new GattService.BluetoothGattBinder(mService);
+ mBinder = new GattServiceBinder(mService);
mAttributionSource = new AttributionSource.Builder(1).build();
}
@@ -68,7 +68,6 @@ public class GattServiceBinderTest {
int[] states = new int[] {STATE_CONNECTED};
mBinder.getDevicesMatchingConnectionStates(states, mAttributionSource);
-
verify(mService).getDevicesMatchingConnectionStates(states, mAttributionSource);
}
@@ -79,7 +78,6 @@ public class GattServiceBinderTest {
boolean eattSupport = true;
mBinder.registerClient(new ParcelUuid(uuid), callback, eattSupport, mAttributionSource);
-
verify(mService).registerClient(uuid, callback, eattSupport, mAttributionSource);
}
@@ -88,7 +86,6 @@ public class GattServiceBinderTest {
int clientIf = 3;
mBinder.unregisterClient(clientIf, mAttributionSource);
-
verify(mService)
.unregisterClient(
clientIf,
@@ -115,7 +112,6 @@ public class GattServiceBinderTest {
opportunistic,
phy,
mAttributionSource);
-
verify(mService)
.clientConnect(
clientIf,
@@ -134,7 +130,6 @@ public class GattServiceBinderTest {
String address = REMOTE_DEVICE_ADDRESS;
mBinder.clientDisconnect(clientIf, address, mAttributionSource);
-
verify(mService).clientDisconnect(clientIf, address, mAttributionSource);
}
@@ -148,7 +143,6 @@ public class GattServiceBinderTest {
mBinder.clientSetPreferredPhy(
clientIf, address, txPhy, rxPhy, phyOptions, mAttributionSource);
-
verify(mService)
.clientSetPreferredPhy(
clientIf, address, txPhy, rxPhy, phyOptions, mAttributionSource);
@@ -160,7 +154,6 @@ public class GattServiceBinderTest {
String address = REMOTE_DEVICE_ADDRESS;
mBinder.clientReadPhy(clientIf, address, mAttributionSource);
-
verify(mService).clientReadPhy(clientIf, address, mAttributionSource);
}
@@ -170,7 +163,6 @@ public class GattServiceBinderTest {
String address = REMOTE_DEVICE_ADDRESS;
mBinder.refreshDevice(clientIf, address, mAttributionSource);
-
verify(mService).refreshDevice(clientIf, address, mAttributionSource);
}
@@ -180,7 +172,6 @@ public class GattServiceBinderTest {
String address = REMOTE_DEVICE_ADDRESS;
mBinder.discoverServices(clientIf, address, mAttributionSource);
-
verify(mService).discoverServices(clientIf, address, mAttributionSource);
}
@@ -191,7 +182,6 @@ public class GattServiceBinderTest {
UUID uuid = UUID.randomUUID();
mBinder.discoverServiceByUuid(clientIf, address, new ParcelUuid(uuid), mAttributionSource);
-
verify(mService).discoverServiceByUuid(clientIf, address, uuid, mAttributionSource);
}
@@ -203,7 +193,6 @@ public class GattServiceBinderTest {
int authReq = 3;
mBinder.readCharacteristic(clientIf, address, handle, authReq, mAttributionSource);
-
verify(mService).readCharacteristic(clientIf, address, handle, authReq, mAttributionSource);
}
@@ -224,7 +213,6 @@ public class GattServiceBinderTest {
endHandle,
authReq,
mAttributionSource);
-
verify(mService)
.readUsingCharacteristicUuid(
clientIf,
@@ -247,7 +235,6 @@ public class GattServiceBinderTest {
mBinder.writeCharacteristic(
clientIf, address, handle, writeType, authReq, value, mAttributionSource);
-
verify(mService)
.writeCharacteristic(
clientIf, address, handle, writeType, authReq, value, mAttributionSource);
@@ -261,7 +248,6 @@ public class GattServiceBinderTest {
int authReq = 3;
mBinder.readDescriptor(clientIf, address, handle, authReq, mAttributionSource);
-
verify(mService).readDescriptor(clientIf, address, handle, authReq, mAttributionSource);
}
@@ -274,7 +260,6 @@ public class GattServiceBinderTest {
byte[] value = new byte[] {4, 5};
mBinder.writeDescriptor(clientIf, address, handle, authReq, value, mAttributionSource);
-
verify(mService)
.writeDescriptor(clientIf, address, handle, authReq, value, mAttributionSource);
}
@@ -285,7 +270,6 @@ public class GattServiceBinderTest {
String address = REMOTE_DEVICE_ADDRESS;
mBinder.beginReliableWrite(clientIf, address, mAttributionSource);
-
verify(mService).beginReliableWrite(clientIf, address, mAttributionSource);
}
@@ -296,7 +280,6 @@ public class GattServiceBinderTest {
boolean execute = true;
mBinder.endReliableWrite(clientIf, address, execute, mAttributionSource);
-
verify(mService).endReliableWrite(clientIf, address, execute, mAttributionSource);
}
@@ -308,7 +291,6 @@ public class GattServiceBinderTest {
boolean enable = true;
mBinder.registerForNotification(clientIf, address, handle, enable, mAttributionSource);
-
verify(mService)
.registerForNotification(clientIf, address, handle, enable, mAttributionSource);
}
@@ -319,7 +301,6 @@ public class GattServiceBinderTest {
String address = REMOTE_DEVICE_ADDRESS;
mBinder.readRemoteRssi(clientIf, address, mAttributionSource);
-
verify(mService).readRemoteRssi(clientIf, address, mAttributionSource);
}
@@ -330,7 +311,6 @@ public class GattServiceBinderTest {
int mtu = 2;
mBinder.configureMTU(clientIf, address, mtu, mAttributionSource);
-
verify(mService).configureMTU(clientIf, address, mtu, mAttributionSource);
}
@@ -342,7 +322,6 @@ public class GattServiceBinderTest {
mBinder.connectionParameterUpdate(
clientIf, address, connectionPriority, mAttributionSource);
-
verify(mService)
.connectionParameterUpdate(
clientIf, address, connectionPriority, mAttributionSource);
@@ -369,7 +348,6 @@ public class GattServiceBinderTest {
minConnectionEventLen,
maxConnectionEventLen,
mAttributionSource);
-
verify(mService)
.leConnectionUpdate(
clientIf,
@@ -390,7 +368,6 @@ public class GattServiceBinderTest {
boolean eattSupport = true;
mBinder.registerServer(new ParcelUuid(uuid), callback, eattSupport, mAttributionSource);
-
verify(mService).registerServer(uuid, callback, eattSupport, mAttributionSource);
}
@@ -399,7 +376,6 @@ public class GattServiceBinderTest {
int serverIf = 3;
mBinder.unregisterServer(serverIf, mAttributionSource);
-
verify(mService).unregisterServer(serverIf, mAttributionSource);
}
@@ -413,7 +389,6 @@ public class GattServiceBinderTest {
mBinder.serverConnect(
serverIf, address, addressType, isDirect, transport, mAttributionSource);
-
verify(mService)
.serverConnect(
serverIf, address, addressType, isDirect, transport, mAttributionSource);
@@ -425,7 +400,6 @@ public class GattServiceBinderTest {
String address = REMOTE_DEVICE_ADDRESS;
mBinder.serverDisconnect(serverIf, address, mAttributionSource);
-
verify(mService).serverDisconnect(serverIf, address, mAttributionSource);
}
@@ -439,7 +413,6 @@ public class GattServiceBinderTest {
mBinder.serverSetPreferredPhy(
serverIf, address, txPhy, rxPhy, phyOptions, mAttributionSource);
-
verify(mService)
.serverSetPreferredPhy(
serverIf, address, txPhy, rxPhy, phyOptions, mAttributionSource);
@@ -451,7 +424,6 @@ public class GattServiceBinderTest {
String address = REMOTE_DEVICE_ADDRESS;
mBinder.serverReadPhy(serverIf, address, mAttributionSource);
-
verify(mService).serverReadPhy(serverIf, address, mAttributionSource);
}
@@ -461,7 +433,6 @@ public class GattServiceBinderTest {
BluetoothGattService svc = mock(BluetoothGattService.class);
mBinder.addService(serverIf, svc, mAttributionSource);
-
verify(mService).addService(serverIf, svc, mAttributionSource);
}
@@ -471,7 +442,6 @@ public class GattServiceBinderTest {
int handle = 2;
mBinder.removeService(serverIf, handle, mAttributionSource);
-
verify(mService).removeService(serverIf, handle, mAttributionSource);
}
@@ -480,7 +450,6 @@ public class GattServiceBinderTest {
int serverIf = 1;
mBinder.clearServices(serverIf, mAttributionSource);
-
verify(mService).clearServices(serverIf, mAttributionSource);
}
@@ -495,7 +464,6 @@ public class GattServiceBinderTest {
mBinder.sendResponse(
serverIf, address, requestId, status, offset, value, mAttributionSource);
-
verify(mService)
.sendResponse(
serverIf, address, requestId, status, offset, value, mAttributionSource);
@@ -510,7 +478,6 @@ public class GattServiceBinderTest {
byte[] value = new byte[] {5, 6};
mBinder.sendNotification(serverIf, address, handle, confirm, value, mAttributionSource);
-
verify(mService)
.sendNotification(serverIf, address, handle, confirm, value, mAttributionSource);
}
@@ -518,12 +485,11 @@ public class GattServiceBinderTest {
@Test
public void disconnectAll() throws Exception {
mBinder.disconnectAll(mAttributionSource);
-
verify(mService).disconnectAll(mAttributionSource);
}
@Test
- public void cleanUp_doesNotCrash() {
+ public void cleanup_doesNotCrash() {
mBinder.cleanup();
}
}
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 f52702a24b..76d6dd53ff 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 The Android Open Source Project
+ * Copyright (C) 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/hap/HapClientNativeCallbackTest.java b/android/app/tests/unit/src/com/android/bluetooth/hap/HapClientNativeCallbackTest.java
index a67995ffae..5e1218b202 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/hap/HapClientNativeCallbackTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/hap/HapClientNativeCallbackTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 The Android Open Source Project
+ * Copyright (C) 2024 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/hap/HapClientBinderTest.java b/android/app/tests/unit/src/com/android/bluetooth/hap/HapClientServiceBinderTest.java
index 7f079c79b7..3544578497 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/hap/HapClientBinderTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/hap/HapClientServiceBinderTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 The Android Open Source Project
+ * Copyright (C) 2024 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.
@@ -44,9 +44,10 @@ import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
+/** Test cases for {@link HapClientServiceBinder} */
@MediumTest
@RunWith(AndroidJUnit4.class)
-public class HapClientBinderTest {
+public class HapClientServiceBinderTest {
@Rule public final MockitoRule mMockitoRule = new MockitoRule();
@Mock private HapClientService mHapClientService;
@@ -59,11 +60,11 @@ public class HapClientBinderTest {
private final AttributionSource mAttributionSource = mAdapter.getAttributionSource();
private final BluetoothDevice mDevice = getTestDevice(0);
- private HapClientBinder mBinder;
+ private HapClientServiceBinder mBinder;
@Before
public void setUp() throws Exception {
- mBinder = new HapClientBinder(mHapClientService);
+ mBinder = new HapClientServiceBinder(mHapClientService);
}
@Test
diff --git a/android/app/tests/unit/src/com/android/bluetooth/hap/HapClientStackEventTest.java b/android/app/tests/unit/src/com/android/bluetooth/hap/HapClientStackEventTest.java
index 249914b644..01a12b7a9b 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/hap/HapClientStackEventTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/hap/HapClientStackEventTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
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 ac7c90a213..6b32743a7b 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/hearingaid/HearingAidServiceBinderTest.java b/android/app/tests/unit/src/com/android/bluetooth/hearingaid/HearingAidServiceBinderTest.java
new file mode 100644
index 0000000000..8dae3bf594
--- /dev/null
+++ b/android/app/tests/unit/src/com/android/bluetooth/hearingaid/HearingAidServiceBinderTest.java
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.bluetooth.hearingaid;
+
+import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_ALLOWED;
+import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
+import static android.bluetooth.BluetoothProfile.STATE_CONNECTED;
+import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTED;
+
+import static com.android.bluetooth.TestUtils.MockitoRule;
+import static com.android.bluetooth.TestUtils.getTestDevice;
+
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothHearingAid;
+import android.bluetooth.BluetoothManager;
+import android.content.AttributionSource;
+import android.content.Context;
+
+import androidx.test.InstrumentationRegistry;
+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 java.util.ArrayList;
+import java.util.List;
+
+/** Test cases for {@link HearingAidServiceBinder} */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class HearingAidServiceBinderTest {
+
+ @Rule public final MockitoRule mMockitoRule = new MockitoRule();
+
+ @Mock private HearingAidService mService;
+
+ private HearingAidServiceBinder mBinder;
+ private AttributionSource mAttributionSource;
+ private BluetoothDevice mTestDevice;
+
+ @Before
+ public void setUp() throws Exception {
+ when(mService.isAvailable()).thenReturn(true);
+ mBinder = new HearingAidServiceBinder(mService);
+ Context context = InstrumentationRegistry.getTargetContext();
+ mAttributionSource =
+ context.getSystemService(BluetoothManager.class)
+ .getAdapter()
+ .getAttributionSource();
+ mTestDevice = getTestDevice(0);
+ }
+
+ @Test
+ public void connect() {
+ mBinder.connect(mTestDevice, mAttributionSource);
+ verify(mService).connect(mTestDevice);
+ }
+
+ @Test
+ public void disconnect() {
+ mBinder.disconnect(mTestDevice, mAttributionSource);
+ verify(mService).disconnect(mTestDevice);
+ }
+
+ @Test
+ public void getConnectedDevices() {
+ List<BluetoothDevice> connectedDevices = new ArrayList<>();
+ connectedDevices.add(mTestDevice);
+ when(mService.getConnectedDevices()).thenReturn(connectedDevices);
+
+ mBinder.getConnectedDevices(mAttributionSource);
+ verify(mService).getConnectedDevices();
+ }
+
+ @Test
+ public void getDevicesMatchingConnectionStates() {
+ int[] states = new int[] {STATE_CONNECTED, STATE_DISCONNECTED};
+ List<BluetoothDevice> devices = new ArrayList<>();
+ devices.add(mTestDevice);
+ when(mService.getDevicesMatchingConnectionStates(states)).thenReturn(devices);
+
+ mBinder.getDevicesMatchingConnectionStates(states, mAttributionSource);
+ verify(mService).getDevicesMatchingConnectionStates(states);
+ }
+
+ @Test
+ public void getConnectionState() {
+ when(mService.getConnectionState(mTestDevice)).thenReturn(STATE_CONNECTED);
+
+ mBinder.getConnectionState(mTestDevice, mAttributionSource);
+ verify(mService).getConnectionState(mTestDevice);
+ }
+
+ @Test
+ public void setActiveDevice() {
+ mBinder.setActiveDevice(mTestDevice, mAttributionSource);
+ verify(mService).setActiveDevice(mTestDevice);
+ }
+
+ @Test
+ public void removeActiveDevice() {
+ mBinder.setActiveDevice(null, mAttributionSource);
+ verify(mService).removeActiveDevice(false);
+ }
+
+ @Test
+ public void getActiveDevices() {
+ List<BluetoothDevice> activeDevices = new ArrayList<>();
+ activeDevices.add(mTestDevice);
+ when(mService.getActiveDevices()).thenReturn(activeDevices);
+
+ mBinder.getActiveDevices(mAttributionSource);
+ verify(mService).getActiveDevices();
+ }
+
+ @Test
+ public void setConnectionPolicy() {
+ mBinder.setConnectionPolicy(mTestDevice, CONNECTION_POLICY_ALLOWED, mAttributionSource);
+ verify(mService).setConnectionPolicy(mTestDevice, CONNECTION_POLICY_ALLOWED);
+ }
+
+ @Test
+ public void getConnectionPolicy() {
+ when(mService.getConnectionPolicy(mTestDevice)).thenReturn(CONNECTION_POLICY_FORBIDDEN);
+
+ mBinder.getConnectionPolicy(mTestDevice, mAttributionSource);
+ verify(mService).getConnectionPolicy(mTestDevice);
+ }
+
+ @Test
+ public void setVolume() {
+ int volume = 50;
+
+ mBinder.setVolume(volume, mAttributionSource);
+ verify(mService).setVolume(volume);
+ }
+
+ @Test
+ public void getHiSyncId() {
+ long hiSyncId = 1234567890L;
+ when(mService.getHiSyncId(mTestDevice)).thenReturn(hiSyncId);
+
+ mBinder.getHiSyncId(mTestDevice, mAttributionSource);
+ verify(mService).getHiSyncId(mTestDevice);
+ }
+
+ @Test
+ public void getDeviceSide() {
+ int side = BluetoothHearingAid.SIDE_LEFT;
+ when(mService.getCapabilities(mTestDevice)).thenReturn(side);
+
+ mBinder.getDeviceSide(mTestDevice, mAttributionSource);
+ verify(mService).getCapabilities(mTestDevice);
+ }
+
+ @Test
+ public void getDeviceMode() {
+ int mode = BluetoothHearingAid.MODE_BINAURAL;
+ when(mService.getCapabilities(mTestDevice)).thenReturn(mode << 1);
+
+ mBinder.getDeviceMode(mTestDevice, mAttributionSource);
+ verify(mService).getCapabilities(mTestDevice);
+ }
+
+ @Test
+ public void getAdvertisementServiceData() {
+ BluetoothHearingAid.AdvertisementServiceData data =
+ new BluetoothHearingAid.AdvertisementServiceData(0, 0);
+ when(mService.getAdvertisementServiceData(mTestDevice)).thenReturn(data);
+
+ mBinder.getAdvertisementServiceData(mTestDevice, mAttributionSource);
+ verify(mService).getAdvertisementServiceData(mTestDevice);
+ }
+
+ @Test
+ public void cleanup_doesNotCrash() {
+ mBinder.cleanup();
+ }
+}
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 69bcca1087..a284d6a414 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 The Android Open Source Project
+ * Copyright (C) 2018 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.
@@ -97,7 +97,7 @@ public class HearingAidServiceTest {
private final BluetoothDevice mSingleDevice = getTestDevice(13);
private HearingAidService mService;
- private HearingAidService.BluetoothHearingAidBinder mBinder;
+ private HearingAidServiceBinder mBinder;
private InOrder mInOrder;
private TestLooper mLooper;
@@ -124,7 +124,7 @@ public class HearingAidServiceTest {
mService = new HearingAidService(mAdapterService, mLooper.getLooper(), mNativeInterface);
mService.setAvailable(true);
- mBinder = (HearingAidService.BluetoothHearingAidBinder) mService.initBinder();
+ mBinder = (HearingAidServiceBinder) mService.initBinder();
}
@After
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 20feec9b8a..07cd5703ff 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 The Android Open Source Project
+ * Copyright (C) 2018 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.
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 123b34c178..b54da60e79 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetAgIndicatorEnableStateTest.java b/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetAgIndicatorEnableStateTest.java
index f034bf44cf..8fa050b679 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetAgIndicatorEnableStateTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetAgIndicatorEnableStateTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetClccResponseTest.java b/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetClccResponseTest.java
index 3f6603ff3a..63e0f2632d 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetClccResponseTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetClccResponseTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
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 cdd59bfce3..edcf484239 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 The Android Open Source Project
+ * Copyright (C) 2018 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.
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 d4b2b39825..835f03aaa2 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 The Android Open Source Project
+ * Copyright (C) 2018 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.
@@ -172,7 +172,9 @@ public class HeadsetServiceAndStateMachineTest {
doReturn(true).when(mNativeInterface).disconnectAudio(any(BluetoothDevice.class));
doReturn(true).when(mNativeInterface).setActiveDevice(any(BluetoothDevice.class));
doReturn(true).when(mNativeInterface).sendBsir(any(BluetoothDevice.class), anyBoolean());
- doReturn(true).when(mNativeInterface).startVoiceRecognition(any(BluetoothDevice.class));
+ doReturn(true)
+ .when(mNativeInterface)
+ .startVoiceRecognition(any(BluetoothDevice.class), anyBoolean());
doReturn(true).when(mNativeInterface).stopVoiceRecognition(any(BluetoothDevice.class));
doReturn(true)
.when(mNativeInterface)
@@ -1138,7 +1140,7 @@ public class HeadsetServiceAndStateMachineTest {
mTestLooper.dispatchAll();
verify(mNativeInterface).setActiveDevice(deviceA);
assertThat(mHeadsetService.getActiveDevice()).isEqualTo(deviceA);
- verify(mNativeInterface).startVoiceRecognition(deviceA);
+ verify(mNativeInterface).startVoiceRecognition(deviceA, true);
verify(mAudioManager).setA2dpSuspended(true);
verify(mAudioManager).setLeAudioSuspended(true);
verify(mNativeInterface).connectAudio(deviceA);
@@ -1685,6 +1687,7 @@ public class HeadsetServiceAndStateMachineTest {
// has not add verification AudioDeviceInfo because it is final, unless add a wrapper
mHeadsetService.startVoiceRecognition(device);
mTestLooper.dispatchAll();
+ verify(mNativeInterface).startVoiceRecognition(device, false);
verify(mAudioManager, times(0)).setA2dpSuspended(true);
verify(mAudioManager, times(0)).setLeAudioSuspended(true);
verify(mNativeInterface, times(0)).connectAudio(device);
@@ -1695,7 +1698,7 @@ public class HeadsetServiceAndStateMachineTest {
assertThat(device).isNotNull();
assertThat(mHeadsetService.startVoiceRecognition(device)).isTrue();
mTestLooper.dispatchAll();
- verify(mNativeInterface).startVoiceRecognition(device);
+ verify(mNativeInterface).startVoiceRecognition(device, true);
verify(mAudioManager).setA2dpSuspended(true);
verify(mAudioManager).setLeAudioSuspended(true);
verify(mNativeInterface).connectAudio(device);
@@ -1727,7 +1730,7 @@ public class HeadsetServiceAndStateMachineTest {
mHeadsetService.startVoiceRecognition(device);
mTestLooper.dispatchAll();
// has not add verification AudioDeviceInfo because it is final, unless add a wrapper
- verify(mNativeInterface).startVoiceRecognition(device);
+ verify(mNativeInterface).startVoiceRecognition(device, true);
verify(mAudioManager, times(0)).setA2dpSuspended(true);
verify(mAudioManager, times(0)).setLeAudioSuspended(true);
verify(mNativeInterface, times(0)).connectAudio(device);
diff --git a/android/app/tests/unit/src/com/android/bluetooth/hfp/BluetoothHeadsetBinderTest.java b/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetServiceBinderTest.java
index 398ba1c6cd..73f3610505 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/hfp/BluetoothHeadsetBinderTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetServiceBinderTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -27,12 +27,20 @@ import static org.mockito.Mockito.verify;
import android.bluetooth.BluetoothDevice;
import android.content.AttributionSource;
+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;
-public class BluetoothHeadsetBinderTest {
+/** Test cases for {@link HeadsetServiceBinder} */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class HeadsetServiceBinderTest {
+
@Rule public final MockitoRule mMockitoRule = new MockitoRule();
@Mock private HeadsetService mService;
@@ -40,11 +48,11 @@ public class BluetoothHeadsetBinderTest {
private final AttributionSource mAttributionSource = new AttributionSource.Builder(1).build();
private final BluetoothDevice mDevice = getTestDevice(39);
- private HeadsetService.BluetoothHeadsetBinder mBinder;
+ private HeadsetServiceBinder mBinder;
@Before
public void setUp() throws Exception {
- mBinder = new HeadsetService.BluetoothHeadsetBinder(mService);
+ mBinder = new HeadsetServiceBinder(mService);
}
@Test
@@ -68,6 +76,7 @@ public class BluetoothHeadsetBinderTest {
@Test
public void getDevicesMatchingConnectionStates() {
int[] states = new int[] {STATE_CONNECTED};
+
mBinder.getDevicesMatchingConnectionStates(states, mAttributionSource);
verify(mService).getDevicesMatchingConnectionStates(states);
}
@@ -142,6 +151,7 @@ public class BluetoothHeadsetBinderTest {
@Test
public void setAudioRouteAllowed() {
boolean allowed = true;
+
mBinder.setAudioRouteAllowed(allowed, mAttributionSource);
verify(mService).setAudioRouteAllowed(allowed);
}
@@ -155,6 +165,7 @@ public class BluetoothHeadsetBinderTest {
@Test
public void setForceScoAudio() {
boolean forced = true;
+
mBinder.setForceScoAudio(forced, mAttributionSource);
verify(mService).setForceScoAudio(forced);
}
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 18a53db436..b16578c823 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 The Android Open Source Project
+ * Copyright (C) 2018 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetStackEventTest.java b/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetStackEventTest.java
index bf90084521..d5f66da856 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetStackEventTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetStackEventTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
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 c824c3be86..68c17a10f8 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2017 The Android Open Source Project
+ * Copyright (C) 2017 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetTestUtils.java b/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetTestUtils.java
index 4b2d0b291c..b504414050 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetTestUtils.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetTestUtils.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 The Android Open Source Project
+ * Copyright (C) 2018 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetVendorSpecificResultCodeTest.java b/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetVendorSpecificResultCodeTest.java
index 7b2b72923e..cfb1dea03c 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetVendorSpecificResultCodeTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetVendorSpecificResultCodeTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
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 e96fc3a9a6..3a1a31d085 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -35,6 +35,7 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
+/** Test cases for {@link HeadsetClientServiceBinder} */
@SmallTest
@RunWith(AndroidJUnit4.class)
public class HeadsetClientServiceBinderTest {
@@ -44,11 +45,11 @@ public class HeadsetClientServiceBinderTest {
private final BluetoothDevice mDevice = getTestDevice(54);
- HeadsetClientService.BluetoothHeadsetClientBinder mBinder;
+ private HeadsetClientServiceBinder mBinder;
@Before
public void setUp() throws Exception {
- mBinder = new HeadsetClientService.BluetoothHeadsetClientBinder(mService);
+ mBinder = new HeadsetClientServiceBinder(mService);
}
@Test
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 d4cb896827..a8a81b0440 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2017 The Android Open Source Project
+ * Copyright (C) 2017 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.
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 e3f54ca620..7e47efeb4a 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2016 The Android Open Source Project
+ * Copyright (C) 2016 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.
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 d47e70da86..bd480693e8 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/hfpclient/StackEventTest.java b/android/app/tests/unit/src/com/android/bluetooth/hfpclient/StackEventTest.java
index 7aaba84f59..cb397e29ec 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/hfpclient/StackEventTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/hfpclient/StackEventTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
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 17af0e42bc..0c9522b05b 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
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 787eaacb86..d393b8dc65 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/hid/BluetoothHidDeviceBinderTest.java b/android/app/tests/unit/src/com/android/bluetooth/hid/HidDeviceServiceBinderTest.java
index 4b11bc7b2a..4369e85310 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/hid/BluetoothHidDeviceBinderTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/hid/HidDeviceServiceBinderTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -33,12 +33,20 @@ import android.bluetooth.BluetoothHidDeviceAppSdpSettings;
import android.bluetooth.IBluetoothHidDeviceCallback;
import android.content.AttributionSource;
+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;
-public class BluetoothHidDeviceBinderTest {
+/** Test cases for {@link HidDeviceServiceBinder} */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class HidDeviceServiceBinderTest {
+
@Rule public final MockitoRule mMockitoRule = new MockitoRule();
@Mock private HidDeviceService mService;
@@ -46,12 +54,12 @@ public class BluetoothHidDeviceBinderTest {
private final AttributionSource mAttributionSource = new AttributionSource.Builder(1).build();
private final BluetoothDevice mDevice = getTestDevice(29);
- private HidDeviceService.BluetoothHidDeviceBinder mBinder;
+ private HidDeviceServiceBinder mBinder;
@Before
public void setUp() throws Exception {
when(mService.isAvailable()).thenReturn(true);
- mBinder = new HidDeviceService.BluetoothHidDeviceBinder(mService);
+ mBinder = new HidDeviceServiceBinder(mService);
}
@Test
diff --git a/android/app/tests/unit/src/com/android/bluetooth/hid/HidDeviceTest.java b/android/app/tests/unit/src/com/android/bluetooth/hid/HidDeviceServiceTest.java
index de64564c77..a242f054a7 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/hid/HidDeviceTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/hid/HidDeviceServiceTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017 The Android Open Source Project
+ * Copyright (C) 2017 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.
@@ -76,7 +76,7 @@ import org.mockito.hamcrest.MockitoHamcrest;
@MediumTest
@RunWith(AndroidJUnit4.class)
-public class HidDeviceTest {
+public class HidDeviceServiceTest {
@Rule public final MockitoRule mMockitoRule = new MockitoRule();
@Mock private AdapterService mAdapterService;
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 946d9a7c93..e2b15ebdba 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -36,9 +36,11 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
+/** Test cases for {@link HidHostServiceBinder}. */
@SmallTest
@RunWith(AndroidJUnit4.class)
public class HidHostServiceBinderTest {
+
@Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
@Rule public final MockitoRule mMockitoRule = new MockitoRule();
@@ -46,98 +48,90 @@ public class HidHostServiceBinderTest {
private final BluetoothDevice mDevice = getTestDevice(50);
- private HidHostService.BluetoothHidHostBinder mBinder;
+ private HidHostServiceBinder mBinder;
@Before
public void setUp() {
- mBinder = new HidHostService.BluetoothHidHostBinder(mService);
+ mBinder = new HidHostServiceBinder(mService);
}
@Test
public void connect_callsServiceMethod() {
mBinder.connect(mDevice, null);
-
verify(mService).connect(mDevice);
}
@Test
public void disconnect_callsServiceMethod() {
mBinder.disconnect(mDevice, null);
-
verify(mService).disconnect(mDevice);
}
@Test
public void getConnectedDevices_callsServiceMethod() {
mBinder.getConnectedDevices(null);
-
verify(mService).getDevicesMatchingConnectionStates(new int[] {STATE_CONNECTED});
}
@Test
public void getDevicesMatchingConnectionStates_callsServiceMethod() {
int[] states = new int[] {STATE_CONNECTED};
- mBinder.getDevicesMatchingConnectionStates(states, null);
+ mBinder.getDevicesMatchingConnectionStates(states, null);
verify(mService).getDevicesMatchingConnectionStates(states);
}
@Test
public void getConnectionState_callsServiceMethod() {
mBinder.getConnectionState(mDevice, null);
-
verify(mService).getConnectionState(mDevice);
}
@Test
public void setConnectionPolicy_callsServiceMethod() {
int connectionPolicy = CONNECTION_POLICY_ALLOWED;
- mBinder.setConnectionPolicy(mDevice, connectionPolicy, null);
+ mBinder.setConnectionPolicy(mDevice, connectionPolicy, null);
verify(mService).setConnectionPolicy(mDevice, connectionPolicy);
}
@Test
public void getConnectionPolicy_callsServiceMethod() {
mBinder.getConnectionPolicy(mDevice, null);
-
verify(mService).getConnectionPolicy(mDevice);
}
@Test
public void setPreferredTransport_callsServiceMethod() {
int preferredTransport = BluetoothDevice.TRANSPORT_AUTO;
- mBinder.setPreferredTransport(mDevice, preferredTransport, null);
+ mBinder.setPreferredTransport(mDevice, preferredTransport, null);
verify(mService).setPreferredTransport(mDevice, preferredTransport);
}
@Test
public void getPreferredTransport_callsServiceMethod() {
mBinder.getPreferredTransport(mDevice, null);
-
verify(mService).getPreferredTransport(mDevice);
}
@Test
public void getProtocolMode_callsServiceMethod() {
mBinder.getProtocolMode(mDevice, null);
-
verify(mService).getProtocolMode(mDevice);
}
@Test
public void virtualUnplug_callsServiceMethod() {
mBinder.virtualUnplug(mDevice, null);
-
verify(mService).virtualUnplug(mDevice);
}
@Test
public void setProtocolMode_callsServiceMethod() {
int protocolMode = 1;
- mBinder.setProtocolMode(mDevice, protocolMode, null);
+ mBinder.setProtocolMode(mDevice, protocolMode, null);
verify(mService).setProtocolMode(mDevice, protocolMode);
}
@@ -146,8 +140,8 @@ public class HidHostServiceBinderTest {
byte reportType = 1;
byte reportId = 2;
int bufferSize = 16;
- mBinder.getReport(mDevice, reportType, reportId, bufferSize, null);
+ mBinder.getReport(mDevice, reportType, reportId, bufferSize, null);
verify(mService).getReport(mDevice, reportType, reportId, bufferSize);
}
@@ -155,31 +149,30 @@ public class HidHostServiceBinderTest {
public void setReport_callsServiceMethod() {
byte reportType = 1;
String report = "test_report";
- mBinder.setReport(mDevice, reportType, report, null);
+ mBinder.setReport(mDevice, reportType, report, null);
verify(mService).setReport(mDevice, reportType, report);
}
@Test
public void sendData_callsServiceMethod() {
String report = "test_report";
- mBinder.sendData(mDevice, report, null);
+ mBinder.sendData(mDevice, report, null);
verify(mService).sendData(mDevice, report);
}
@Test
public void setIdleTime_callsServiceMethod() {
byte idleTime = 1;
- mBinder.setIdleTime(mDevice, idleTime, null);
+ mBinder.setIdleTime(mDevice, idleTime, null);
verify(mService).setIdleTime(mDevice, idleTime);
}
@Test
public void getIdleTime_callsServiceMethod() {
mBinder.getIdleTime(mDevice, null);
-
verify(mService).getIdleTime(mDevice);
}
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 341cd54333..10f5f3257f 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 The Android Open Source Project
+ * Copyright (C) 2018 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.
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package com.android.bluetooth.hid;
import static android.bluetooth.BluetoothDevice.BOND_BONDED;
@@ -53,6 +54,7 @@ import java.util.List;
@MediumTest
@RunWith(AndroidJUnit4.class)
public class HidHostServiceTest {
+
@Rule public final MockitoRule mMockitoRule = new MockitoRule();
@Mock private AdapterService mAdapterService;
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 576f7cdc54..e1569ea836 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
@@ -1438,7 +1438,11 @@ public class LeAudioBroadcastServiceTest {
}
@Test
- @DisableFlags(Flags.FLAG_LEAUDIO_BROADCAST_PRIMARY_GROUP_SELECTION)
+ @DisableFlags({
+ Flags.FLAG_LEAUDIO_BROADCAST_PRIMARY_GROUP_SELECTION,
+ Flags.FLAG_LEAUDIO_BROADCAST_API_MANAGE_PRIMARY_GROUP,
+ Flags.FLAG_LEAUDIO_USE_AUDIO_RECORDING_LISTENER
+ })
public void testUpdateFallbackInputDevice() {
int groupId = 1;
int groupId2 = 2;
@@ -1663,57 +1667,6 @@ public class LeAudioBroadcastServiceTest {
}
@Test
- @EnableFlags({
- Flags.FLAG_LEAUDIO_BROADCAST_API_MANAGE_PRIMARY_GROUP,
- Flags.FLAG_LEAUDIO_BROADCAST_PRIMARY_GROUP_SELECTION
- })
- public void testUpdateFallbackDeviceWhileSettingActiveDevice() throws RemoteException {
- int groupId = 1;
- int groupId2 = 2;
- int broadcastId = 243;
- byte[] code = {0x00, 0x01, 0x00, 0x02};
- List<BluetoothDevice> devices = new ArrayList<>();
-
- when(mDatabaseManager.getMostRecentlyConnectedDevices()).thenReturn(devices);
-
- synchronized (mService.mLeAudioCallbacks) {
- mService.mLeAudioCallbacks.register(mLeAudioCallbacks);
- }
-
- initializeNative();
- devices.add(mDevice2);
- prepareConnectedUnicastDevice(groupId2, mDevice2);
- devices.add(mDevice);
- prepareHandoverStreamingBroadcast(groupId, broadcastId, code);
-
- /* group 1 is deactivated due to broadcast and group 2 is set by default as broadcast to
- * unicast fallback group (first add device)
- */
- verify(mTbsService, never()).clearInbandRingtoneSupport(eq(mDevice2));
- verify(mTbsService, times(1)).clearInbandRingtoneSupport(eq(mDevice));
-
- /* Earliest connected group (2) become fallback device */
- assertThat(mService.mUnicastGroupIdDeactivatedForBroadcastTransition).isEqualTo(groupId2);
- verify(mLeAudioCallbacks).onBroadcastToUnicastFallbackGroupChanged(groupId2);
-
- Mockito.clearInvocations(mLeAudioCallbacks);
- reset(mAudioManager);
-
- /* Change active device while broadcasting - result in replacing fallback group 2->1 */
- assertThat(mService.setActiveDevice(mDevice)).isTrue();
- TestUtils.waitForLooperToFinishScheduledTask(Looper.getMainLooper());
- assertThat(mService.mUnicastGroupIdDeactivatedForBroadcastTransition).isEqualTo(groupId);
- verify(mLeAudioCallbacks).onBroadcastToUnicastFallbackGroupChanged(groupId);
-
- /* Verify that fallback device is not changed when there is no running broadcast */
- Mockito.clearInvocations(mLeAudioCallbacks);
- verifyBroadcastStopped(broadcastId);
- assertThat(mService.setActiveDevice(mDevice2)).isTrue();
- TestUtils.waitForLooperToFinishScheduledTask(Looper.getMainLooper());
- verify(mLeAudioCallbacks, never()).onBroadcastToUnicastFallbackGroupChanged(anyInt());
- }
-
- @Test
public void registerUnregisterLeBroadcastCallback() {
IBluetoothLeBroadcastCallback callback = Mockito.mock(IBluetoothLeBroadcastCallback.class);
Binder binder = Mockito.mock(Binder.class);
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 d74b6caf53..f9c57e1494 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
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 03d85dfc4d..369304c608 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
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/LeAudioServiceBinderTest.java
index e0093fc003..68677ffedb 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/LeAudioServiceBinderTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -36,15 +36,23 @@ import android.content.AttributionSource;
import android.os.ParcelUuid;
import android.platform.test.flag.junit.SetFlagsRule;
+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.Mockito;
import java.util.UUID;
-public class LeAudioBinderTest {
+/** Test cases for {@link LeAudioServiceBinder} */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class LeAudioServiceBinderTest {
+
@Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
@Rule public final MockitoRule mMockitoRule = new MockitoRule();
@@ -53,11 +61,11 @@ public class LeAudioBinderTest {
private static final String TEST_BROADCAST_NAME = "TEST";
private static final int TEST_QUALITY = BluetoothLeBroadcastSubgroupSettings.QUALITY_STANDARD;
- private LeAudioService.BluetoothLeAudioBinder mBinder;
+ private LeAudioServiceBinder mBinder;
@Before
public void setUp() {
- mBinder = new LeAudioService.BluetoothLeAudioBinder(mService);
+ mBinder = new LeAudioServiceBinder(mService);
}
@Test
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 ff18ff4b8e..cf836ddc3c 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
@@ -76,12 +76,12 @@ import android.os.ParcelUuid;
import android.os.RemoteException;
import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.FlagsParameterization;
import android.platform.test.flag.junit.SetFlagsRule;
import android.sysprop.BluetoothProperties;
import androidx.test.filters.MediumTest;
import androidx.test.platform.app.InstrumentationRegistry;
-import androidx.test.runner.AndroidJUnit4;
import com.android.bluetooth.TestUtils;
import com.android.bluetooth.bass_client.BassClientService;
@@ -113,15 +113,20 @@ import org.mockito.Mockito;
import org.mockito.Spy;
import org.mockito.hamcrest.MockitoHamcrest;
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4;
+import platform.test.runner.parameterized.Parameters;
+
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
+import java.util.Set;
+import java.util.stream.Collectors;
@MediumTest
-@RunWith(AndroidJUnit4.class)
+@RunWith(ParameterizedAndroidJunit4.class)
public class LeAudioServiceTest {
- @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+ @Rule public final SetFlagsRule mSetFlagsRule;
@Rule public final MockitoRule mMockitoRule = new MockitoRule();
@Mock private AdapterService mAdapterService;
@@ -201,6 +206,20 @@ public class LeAudioServiceTest {
private InOrder mInOrder;
+ @Parameters(name = "{0}")
+ public static List<FlagsParameterization> getParams() {
+ return FlagsParameterization.progressionOf(
+ Flags.FLAG_LEAUDIO_BROADCAST_PRIMARY_GROUP_SELECTION,
+ Flags.FLAG_LEAUDIO_CODEC_CONFIG_CALLBACK_ORDER_FIX,
+ Flags.FLAG_LEAUDIO_UNICAST_NO_AVAILABLE_CONTEXTS,
+ Flags.FLAG_LEAUDIO_BROADCAST_API_MANAGE_PRIMARY_GROUP,
+ Flags.FLAG_DO_NOT_HARDCODE_TMAP_ROLE_MASK);
+ }
+
+ public LeAudioServiceTest(FlagsParameterization flags) {
+ mSetFlagsRule = new SetFlagsRule(flags);
+ }
+
@Before
public void setUp() throws Exception {
mInOrder = inOrder(mAdapterService);
@@ -211,11 +230,9 @@ public class LeAudioServiceTest {
doReturn(mTargetContext.getContentResolver()).when(mAdapterService).getContentResolver();
doReturn(MAX_LE_AUDIO_CONNECTIONS).when(mAdapterService).getMaxConnectedAudioDevices();
- doReturn(
- (long) (1 << BluetoothProfile.LE_AUDIO_BROADCAST)
- | (1 << BluetoothProfile.LE_AUDIO))
- .when(mAdapterService)
- .getSupportedProfilesBitMask();
+ injectSupportedProfilesBitMask(
+ Set.of(BluetoothProfile.LE_AUDIO_BROADCAST, BluetoothProfile.LE_AUDIO));
+
doReturn(new ParcelUuid[] {BluetoothUuid.LE_AUDIO})
.when(mAdapterService)
.getRemoteUuids(any(BluetoothDevice.class));
@@ -280,6 +297,43 @@ public class LeAudioServiceTest {
assertThat(LeAudioService.getLeAudioService()).isNull();
}
+ @Test
+ @EnableFlags(Flags.FLAG_DO_NOT_HARDCODE_TMAP_ROLE_MASK)
+ public void testTmapRoleMask() {
+ List<Set<Integer>> powerSet =
+ List.of(
+ Set.of(BluetoothProfile.LE_CALL_CONTROL),
+ Set.of(BluetoothProfile.MCP_SERVER),
+ Set.of(BluetoothProfile.LE_CALL_CONTROL, BluetoothProfile.MCP_SERVER),
+ Set.of(BluetoothProfile.LE_AUDIO_BROADCAST),
+ Set.of(
+ BluetoothProfile.LE_AUDIO_BROADCAST,
+ BluetoothProfile.LE_CALL_CONTROL),
+ Set.of(BluetoothProfile.LE_AUDIO_BROADCAST, BluetoothProfile.MCP_SERVER),
+ Set.of(
+ BluetoothProfile.LE_AUDIO_BROADCAST,
+ BluetoothProfile.LE_CALL_CONTROL,
+ BluetoothProfile.MCP_SERVER));
+
+ List<Integer> tmapMasks =
+ powerSet.stream()
+ .map(
+ set -> {
+ injectSupportedProfilesBitMask(set);
+ LeAudioService service =
+ new LeAudioService(mAdapterService, mNativeInterface);
+ return service.getTmapRoleMask();
+ })
+ .collect(Collectors.toList());
+
+ List<Integer> expectedMasks =
+ powerSet.stream()
+ .map(LeAudioServiceTest::constructTmapRoleMask)
+ .collect(Collectors.toList());
+
+ assertThat(tmapMasks).containsExactly(expectedMasks.toArray()).inOrder();
+ }
+
/** Test getting LeAudio Service: getLeAudioService() */
@Test
public void testGetLeAudioService() {
@@ -1299,7 +1353,11 @@ public class LeAudioServiceTest {
/** Test update unicast fallback active group when broadcast is ongoing */
@Test
- @DisableFlags(Flags.FLAG_LEAUDIO_BROADCAST_PRIMARY_GROUP_SELECTION)
+ @DisableFlags({
+ Flags.FLAG_LEAUDIO_BROADCAST_PRIMARY_GROUP_SELECTION,
+ Flags.FLAG_LEAUDIO_BROADCAST_API_MANAGE_PRIMARY_GROUP,
+ Flags.FLAG_LEAUDIO_USE_AUDIO_RECORDING_LISTENER
+ })
public void testUpdateUnicastFallbackActiveDeviceGroupDuringBroadcast() {
List<BluetoothDevice> devices = new ArrayList<>();
int groupId = 1;
@@ -1784,8 +1842,8 @@ public class LeAudioServiceTest {
/** Test native interface group status message handling */
@Test
+ @EnableFlags(Flags.FLAG_LEAUDIO_CODEC_CONFIG_CALLBACK_ORDER_FIX)
public void testMessageFromNativeGroupCodecConfigChangedNonActiveDevice() {
- mSetFlagsRule.enableFlags(Flags.FLAG_LEAUDIO_CODEC_CONFIG_CALLBACK_ORDER_FIX);
onGroupCodecConfChangedCallbackCalled = false;
injectLocalCodecConfigCapaChanged(INPUT_CAPABILITIES_CONFIG, OUTPUT_CAPABILITIES_CONFIG);
@@ -1870,8 +1928,8 @@ public class LeAudioServiceTest {
/** Test native interface group status message handling */
@Test
+ @EnableFlags(Flags.FLAG_LEAUDIO_CODEC_CONFIG_CALLBACK_ORDER_FIX)
public void testMessageFromNativeGroupCodecConfigChangedActiveDevice_DifferentConfiguration() {
- mSetFlagsRule.enableFlags(Flags.FLAG_LEAUDIO_CODEC_CONFIG_CALLBACK_ORDER_FIX);
onGroupCodecConfChangedCallbackCalled = false;
injectLocalCodecConfigCapaChanged(INPUT_CAPABILITIES_CONFIG, OUTPUT_CAPABILITIES_CONFIG);
@@ -3212,4 +3270,30 @@ public class LeAudioServiceTest {
.sendBroadcastAsUser(
MockitoHamcrest.argThat(AllOf.allOf(matchers)), any(), any(), any());
}
+
+ private void injectSupportedProfilesBitMask(Set<Integer> profiles) {
+ long mask = 0;
+ for (int profile : profiles) {
+ mask |= (long) (1 << profile);
+ }
+ doReturn(mask).when(mAdapterService).getSupportedProfilesBitMask();
+ }
+
+ private static int constructTmapRoleMask(Set<Integer> profiles) {
+ int mask = 0;
+ for (int profile : profiles) {
+ switch (profile) {
+ case BluetoothProfile.LE_CALL_CONTROL:
+ mask |= LeAudioTmapGattServer.TMAP_ROLE_FLAG_CG;
+ break;
+ case BluetoothProfile.MCP_SERVER:
+ mask |= LeAudioTmapGattServer.TMAP_ROLE_FLAG_UMS;
+ break;
+ case BluetoothProfile.LE_AUDIO_BROADCAST:
+ mask |= LeAudioTmapGattServer.TMAP_ROLE_FLAG_BMS;
+ break;
+ }
+ }
+ return mask;
+ }
}
diff --git a/android/app/tests/unit/src/com/android/bluetooth/le_scan/AdvtFilterOnFoundOnLostInfoTest.java b/android/app/tests/unit/src/com/android/bluetooth/le_scan/AdvtFilterOnFoundOnLostInfoTest.java
index aec90ecf29..80e050d866 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/le_scan/AdvtFilterOnFoundOnLostInfoTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/le_scan/AdvtFilterOnFoundOnLostInfoTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
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 dc823ca412..9a37679916 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/le_scan/ScanBinderTest.kt b/android/app/tests/unit/src/com/android/bluetooth/le_scan/ScanBinderTest.kt
new file mode 100644
index 0000000000..3424c48a54
--- /dev/null
+++ b/android/app/tests/unit/src/com/android/bluetooth/le_scan/ScanBinderTest.kt
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.bluetooth.le_scan
+
+import android.app.PendingIntent
+import android.bluetooth.BluetoothDevice
+import android.bluetooth.BluetoothManager
+import android.bluetooth.le.IPeriodicAdvertisingCallback
+import android.bluetooth.le.IScannerCallback
+import android.bluetooth.le.ScanFilter
+import android.bluetooth.le.ScanResult
+import android.bluetooth.le.ScanSettings
+import android.content.Intent
+import android.os.WorkSource
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import androidx.test.platform.app.InstrumentationRegistry
+import com.android.bluetooth.TestUtils.MockitoRule
+import com.android.bluetooth.TestUtils.getTestDevice
+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.mock
+import org.mockito.Mockito.verify
+
+/** Test cases for [ScanBinder] */
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class ScanBinderTest {
+
+ @get:Rule val mockitoRule = MockitoRule()
+
+ @Mock private lateinit var scanController: ScanController
+
+ private val attributionSource =
+ InstrumentationRegistry.getInstrumentation()
+ .targetContext
+ .getSystemService(BluetoothManager::class.java)
+ .adapter
+ .attributionSource
+ private val device: BluetoothDevice = getTestDevice(89)
+ private lateinit var binder: ScanBinder
+
+ @Before
+ fun setUp() {
+ binder = ScanBinder(scanController)
+ }
+
+ @Test
+ fun registerScanner() {
+ val callback = mock(IScannerCallback::class.java)
+ val workSource = mock(WorkSource::class.java)
+
+ binder.registerScanner(callback, workSource, attributionSource)
+ verify(scanController).registerScanner(callback, workSource, attributionSource)
+ }
+
+ @Test
+ fun unregisterScanner() {
+ val scannerId = 1
+
+ binder.unregisterScanner(scannerId, attributionSource)
+ verify(scanController).unregisterScanner(scannerId, attributionSource)
+ }
+
+ @Test
+ fun startScan() {
+ val scannerId = 1
+ val settings = ScanSettings.Builder().build()
+ val filters = listOf<ScanFilter>()
+
+ binder.startScan(scannerId, settings, filters, attributionSource)
+ verify(scanController).startScan(scannerId, settings, filters, attributionSource)
+ }
+
+ @Test
+ fun startScanForIntent() {
+ val intent =
+ PendingIntent.getBroadcast(
+ InstrumentationRegistry.getInstrumentation().targetContext,
+ 0,
+ Intent(),
+ PendingIntent.FLAG_IMMUTABLE,
+ )
+ val settings = ScanSettings.Builder().build()
+ val filters = listOf<ScanFilter>()
+
+ binder.startScanForIntent(intent, settings, filters, attributionSource)
+ verify(scanController).registerPiAndStartScan(intent, settings, filters, attributionSource)
+ }
+
+ @Test
+ fun stopScan_withScannerId() {
+ val scannerId = 1
+
+ binder.stopScan(scannerId, attributionSource)
+ verify(scanController).stopScan(scannerId, attributionSource)
+ }
+
+ @Test
+ fun stopScan_withIntent() {
+ val intent =
+ PendingIntent.getBroadcast(
+ InstrumentationRegistry.getInstrumentation().targetContext,
+ 0,
+ Intent(),
+ PendingIntent.FLAG_IMMUTABLE,
+ )
+
+ binder.stopScanForIntent(intent, attributionSource)
+ verify(scanController).stopScan(intent, attributionSource)
+ }
+
+ @Test
+ fun flushPendingBatchResults() {
+ val scannerId = 1
+
+ binder.flushPendingBatchResults(scannerId, attributionSource)
+ verify(scanController).flushPendingBatchResults(scannerId, attributionSource)
+ }
+
+ @Test
+ fun registerSync() {
+ val scanResult = mock(ScanResult::class.java)
+ val skip = 1
+ val timeout = 2
+ val callback = mock(IPeriodicAdvertisingCallback::class.java)
+
+ binder.registerSync(scanResult, skip, timeout, callback, attributionSource)
+ verify(scanController).registerSync(scanResult, skip, timeout, callback, attributionSource)
+ }
+
+ @Test
+ fun unregisterSync() {
+ val callback = mock(IPeriodicAdvertisingCallback::class.java)
+
+ binder.unregisterSync(callback, attributionSource)
+ verify(scanController).unregisterSync(callback, attributionSource)
+ }
+
+ @Test
+ fun transferSync() {
+ val serviceData = 1
+ val syncHandle = 2
+
+ binder.transferSync(device, serviceData, syncHandle, attributionSource)
+ verify(scanController).transferSync(device, serviceData, syncHandle, attributionSource)
+ }
+
+ @Test
+ fun transferSetInfo() {
+ val serviceData = 1
+ val advHandle = 2
+ val callback = mock(IPeriodicAdvertisingCallback::class.java)
+
+ binder.transferSetInfo(device, serviceData, advHandle, callback, attributionSource)
+ verify(scanController)
+ .transferSetInfo(device, serviceData, advHandle, callback, attributionSource)
+ }
+
+ @Test
+ fun numHwTrackFiltersAvailable() {
+ binder.numHwTrackFiltersAvailable(attributionSource)
+ verify(scanController).numHwTrackFiltersAvailable(attributionSource)
+ }
+
+ @Test
+ fun cleanup_doesNotCrash() {
+ binder.cleanup()
+ }
+}
diff --git a/android/app/tests/unit/src/com/android/bluetooth/le_scan/ScanControllerTest.java b/android/app/tests/unit/src/com/android/bluetooth/le_scan/ScanControllerTest.java
index 8f2b58cdd8..f1d428906b 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/le_scan/ScanControllerTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/le_scan/ScanControllerTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 The Android Open Source Project
+ * Copyright (C) 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/le_scan/ScanFilterQueueTest.java b/android/app/tests/unit/src/com/android/bluetooth/le_scan/ScanFilterQueueTest.java
index 15dc16bbf3..da5a9d8974 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/le_scan/ScanFilterQueueTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/le_scan/ScanFilterQueueTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
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 22d8fed0ac..54a3679ee6 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
@@ -1227,7 +1227,6 @@ public class ScanManagerTest {
}
@Test
- @EnableFlags(Flags.FLAG_BLE_SCAN_ADV_METRICS_REDESIGN)
public void testMetricsAppScanScreenOn() {
// Set filtered scan flag
final boolean isFiltered = true;
@@ -1292,7 +1291,8 @@ public class ScanManagerTest {
0,
true,
false,
- IMPORTANCE_FOREGROUND_SERVICE);
+ IMPORTANCE_FOREGROUND_SERVICE,
+ "");
advanceTime(scanTestDuration);
// Record scan stop
@@ -1317,12 +1317,12 @@ public class ScanManagerTest {
eq(0),
eq(true),
eq(false),
- eq(IMPORTANCE_FOREGROUND_SERVICE));
+ eq(IMPORTANCE_FOREGROUND_SERVICE),
+ eq(""));
}
}
@Test
- @EnableFlags(Flags.FLAG_BLE_SCAN_ADV_METRICS_REDESIGN)
public void testMetricsRadioScanScreenOnOffMultiScan() {
// Set filtered scan flag
final boolean isFiltered = true;
@@ -1390,7 +1390,8 @@ public class ScanManagerTest {
eq((long) ScanManager.SCAN_MODE_LOW_POWER_WINDOW_MS),
eq(true),
eq(scanTestDuration),
- eq(IMPORTANCE_FOREGROUND_SERVICE));
+ eq(IMPORTANCE_FOREGROUND_SERVICE),
+ eq(""));
advanceTime(scanTestDuration);
// Create workSource for the third app
@@ -1430,7 +1431,8 @@ public class ScanManagerTest {
eq((long) ScanManager.SCAN_MODE_BALANCED_WINDOW_MS),
eq(true),
eq(scanTestDuration),
- eq(IMPORTANCE_FOREGROUND_SERVICE));
+ eq(IMPORTANCE_FOREGROUND_SERVICE),
+ eq(""));
advanceTime(scanTestDuration);
// Create workSource for the fourth app
@@ -1467,7 +1469,8 @@ public class ScanManagerTest {
anyLong(),
anyBoolean(),
anyLong(),
- anyInt());
+ anyInt(),
+ eq(""));
advanceTime(scanTestDuration);
// Set as background app
@@ -1492,7 +1495,8 @@ public class ScanManagerTest {
eq((long) ScanManager.SCAN_MODE_LOW_LATENCY_WINDOW_MS),
eq(true),
eq(scanTestDuration * 2),
- eq(IMPORTANCE_FOREGROUND_SERVICE));
+ eq(IMPORTANCE_FOREGROUND_SERVICE),
+ eq(""));
advanceTime(scanTestDuration);
// Get the most aggressive scan client when screen is off
@@ -1521,7 +1525,8 @@ public class ScanManagerTest {
eq((long) SCAN_MODE_SCREEN_OFF_LOW_POWER_WINDOW_MS),
eq(false),
eq(scanTestDuration),
- eq(IMPORTANCE_FOREGROUND_SERVICE + 1));
+ eq(IMPORTANCE_FOREGROUND_SERVICE + 1),
+ eq(""));
advanceTime(scanTestDuration);
// Stop scan for the fourth app
@@ -1538,7 +1543,8 @@ public class ScanManagerTest {
anyLong(),
anyBoolean(),
anyLong(),
- anyInt());
+ anyInt(),
+ eq(""));
advanceTime(scanTestDuration);
// Stop scan for the third app
@@ -1558,7 +1564,8 @@ public class ScanManagerTest {
eq((long) ScanManager.SCAN_MODE_LOW_LATENCY_WINDOW_MS),
eq(true),
eq(scanTestDuration * 2),
- eq(IMPORTANCE_FOREGROUND_SERVICE));
+ eq(IMPORTANCE_FOREGROUND_SERVICE),
+ eq(""));
advanceTime(scanTestDuration);
// Stop scan for the second app
@@ -1578,7 +1585,8 @@ public class ScanManagerTest {
eq((long) ScanManager.SCAN_MODE_BALANCED_WINDOW_MS),
eq(true),
eq(scanTestDuration),
- eq(IMPORTANCE_FOREGROUND_SERVICE));
+ eq(IMPORTANCE_FOREGROUND_SERVICE),
+ eq(""));
advanceTime(scanTestDuration);
// Stop scan for the first app
@@ -1598,7 +1606,8 @@ public class ScanManagerTest {
eq((long) ScanManager.SCAN_MODE_LOW_POWER_WINDOW_MS),
eq(true),
eq(scanTestDuration),
- eq(IMPORTANCE_FOREGROUND_SERVICE));
+ eq(IMPORTANCE_FOREGROUND_SERVICE),
+ eq(""));
}
@Test
diff --git a/android/app/tests/unit/src/com/android/bluetooth/le_scan/ScannerMapTest.java b/android/app/tests/unit/src/com/android/bluetooth/le_scan/ScannerMapTest.java
index e8d31e0552..ea5b2f564f 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/le_scan/ScannerMapTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/le_scan/ScannerMapTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapAccountItemTest.java b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapAccountItemTest.java
index 8e1be7da7f..6e493ee6d5 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapAccountItemTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapAccountItemTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapAppParamsTest.java b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapAppParamsTest.java
index fde49df622..c0defe0c21 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapAppParamsTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapAppParamsTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
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 a336954afe..b131039e99 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2016 The Android Open Source Project
+ * Copyright (C) 2016 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.
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 5014c1fecd..b149953287 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
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 aa203dcdec..6e8f60f5ce 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapConvoListingElementTest.java b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapConvoListingElementTest.java
index f319894d39..da6e865ab3 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapConvoListingElementTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapConvoListingElementTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapConvoListingTest.java b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapConvoListingTest.java
index 97ec95ea25..e333d7b4bb 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapConvoListingTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapConvoListingTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
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 b0239dfd02..87c33d6588 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 The Android Open Source Project
+ * Copyright (C) 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapMessageListingElementTest.java b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapMessageListingElementTest.java
index 81fa5b5122..bf58abaebc 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapMessageListingElementTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapMessageListingElementTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapMessageListingTest.java b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapMessageListingTest.java
index ccc9170eee..d78405aff4 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapMessageListingTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapMessageListingTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
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 4d53d787b6..a5c4b8425e 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 The Android Open Source Project
+ * Copyright (C) 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.
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 6410ebf3f0..b3125460c4 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -35,77 +35,73 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
+/** Test cases for {@link BluetoothMapServiceBinder} */
@SmallTest
@RunWith(AndroidJUnit4.class)
public class BluetoothMapServiceBinderTest {
+
@Rule public final MockitoRule mMockitoRule = new MockitoRule();
@Mock private BluetoothMapService mService;
private final BluetoothDevice mDevice = getTestDevice(98);
- private BluetoothMapService.BluetoothMapBinder mBinder;
+ private BluetoothMapServiceBinder mBinder;
@Before
public void setUp() throws Exception {
- mBinder = new BluetoothMapService.BluetoothMapBinder(mService);
+ mBinder = new BluetoothMapServiceBinder(mService);
}
@Test
public void disconnect_callsServiceMethod() {
mBinder.disconnect(mDevice, null);
-
verify(mService).disconnect(mDevice);
}
@Test
public void getConnectedDevices_callsServiceMethod() {
mBinder.getConnectedDevices(null);
-
verify(mService).getConnectedDevices();
}
@Test
public void getDevicesMatchingConnectionStates_callsServiceMethod() {
int[] states = new int[] {STATE_CONNECTED};
- mBinder.getDevicesMatchingConnectionStates(states, null);
+ mBinder.getDevicesMatchingConnectionStates(states, null);
verify(mService).getDevicesMatchingConnectionStates(states);
}
@Test
public void getConnectionState_callsServiceMethod() {
mBinder.getConnectionState(mDevice, null);
-
verify(mService).getConnectionState(mDevice);
}
@Test
public void setConnectionPolicy_callsServiceMethod() {
int connectionPolicy = CONNECTION_POLICY_ALLOWED;
- mBinder.setConnectionPolicy(mDevice, connectionPolicy, null);
+ mBinder.setConnectionPolicy(mDevice, connectionPolicy, null);
verify(mService).setConnectionPolicy(mDevice, connectionPolicy);
}
@Test
public void getConnectionPolicy_callsServiceMethod() {
mBinder.getConnectionPolicy(mDevice, null);
-
verify(mService).getConnectionPolicy(mDevice);
}
@Test
public void getState_callsServiceMethod() {
mBinder.getState(null);
-
verify(mService).getState();
}
@Test
public void isConnected_callsServiceStaticMethod() {
mBinder.isConnected(mDevice, null);
-
verify(mService).getConnectionState(mDevice);
}
@@ -116,7 +112,7 @@ public class BluetoothMapServiceBinderTest {
}
@Test
- public void cleanUp_doesNotCrash() {
+ public void cleanup_doesNotCrash() {
mBinder.cleanup();
}
}
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 2f6604a486..f2c455bbc1 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 The Android Open Source Project
+ * Copyright (C) 2018 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.
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 285d056242..2f96c2ead9 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapUtilsTest.java b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapUtilsTest.java
index 7bc752db8a..57467027e1 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapUtilsTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapUtilsTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapbMessageEmailTest.java b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapbMessageEmailTest.java
index 2dab97af35..b3094670e2 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapbMessageEmailTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapbMessageEmailTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapbMessageSmsTest.java b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapbMessageSmsTest.java
index 9ef731fd90..9cec017f97 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapbMessageSmsTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapbMessageSmsTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapbMessageTest.java b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapbMessageTest.java
index 1344d9b0f6..d778b412a6 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapbMessageTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapbMessageTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapbMessageVCardTest.java b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapbMessageVCardTest.java
index a44bd9cfda..69a57b83b2 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapbMessageVCardTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapbMessageVCardTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/map/ConvoContactInfoTest.java b/android/app/tests/unit/src/com/android/bluetooth/map/ConvoContactInfoTest.java
index 170c9e762f..fc99e7134e 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/map/ConvoContactInfoTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/map/ConvoContactInfoTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/map/EventTest.java b/android/app/tests/unit/src/com/android/bluetooth/map/EventTest.java
index d1962fc37b..edd0863d4b 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/map/EventTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/map/EventTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/map/FilterInfoTest.java b/android/app/tests/unit/src/com/android/bluetooth/map/FilterInfoTest.java
index 09183cab1f..7042e34980 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/map/FilterInfoTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/map/FilterInfoTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/map/MapContactTest.java b/android/app/tests/unit/src/com/android/bluetooth/map/MapContactTest.java
index ea0490b173..93babf8f81 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/map/MapContactTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/map/MapContactTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/map/MsgTest.java b/android/app/tests/unit/src/com/android/bluetooth/map/MsgTest.java
index f9f0b50fa1..4a0963cd78 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/map/MsgTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/map/MsgTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
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 1397f06280..fdf2ee67e1 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/mapapi/BluetoothMapContractTest.java b/android/app/tests/unit/src/com/android/bluetooth/mapapi/BluetoothMapContractTest.java
index 8462d664f6..021c1ae82f 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/mapapi/BluetoothMapContractTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/mapapi/BluetoothMapContractTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
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 46c9d8a9cc..1dadfd906d 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
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 26913ee0a2..2fccf754e5 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/mapclient/EventReportTest.java b/android/app/tests/unit/src/com/android/bluetooth/mapclient/EventReportTest.java
index 3c355e1ad1..05facb51cc 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/mapclient/EventReportTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/mapclient/EventReportTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
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 d3e98577a6..a67a5c3981 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -35,70 +35,67 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
+/** Test cases for {@link MapClientServiceBinder} */
@MediumTest
@RunWith(AndroidJUnit4.class)
public class MapClientServiceBinderTest {
+
@Rule public final MockitoRule mMockitoRule = new MockitoRule();
@Mock private MapClientService mService;
private final BluetoothDevice mDevice = getTestDevice(65);
- MapClientService.Binder mBinder;
+ private MapClientServiceBinder mBinder;
@Before
public void setUp() {
- mBinder = new MapClientService.Binder(mService);
+ mBinder = new MapClientServiceBinder(mService);
}
@Test
public void connect_callsServiceMethod() {
mBinder.connect(mDevice, null);
-
verify(mService).connect(mDevice);
}
@Test
public void disconnect_callsServiceMethod() {
mBinder.disconnect(mDevice, null);
-
verify(mService).disconnect(mDevice);
}
@Test
public void getConnectedDevices_callsServiceMethod() {
mBinder.getConnectedDevices(null);
-
verify(mService).getConnectedDevices();
}
@Test
public void getDevicesMatchingConnectionStates_callsServiceMethod() {
int[] states = new int[] {STATE_CONNECTED};
- mBinder.getDevicesMatchingConnectionStates(states, null);
+ mBinder.getDevicesMatchingConnectionStates(states, null);
verify(mService).getDevicesMatchingConnectionStates(states);
}
@Test
public void getConnectionState_callsServiceMethod() {
mBinder.getConnectionState(mDevice, null);
-
verify(mService).getConnectionState(mDevice);
}
@Test
public void setConnectionPolicy_callsServiceMethod() {
int connectionPolicy = CONNECTION_POLICY_ALLOWED;
- mBinder.setConnectionPolicy(mDevice, connectionPolicy, null);
+ mBinder.setConnectionPolicy(mDevice, connectionPolicy, null);
verify(mService).setConnectionPolicy(mDevice, connectionPolicy);
}
@Test
public void getConnectionPolicy_callsServiceMethod() {
mBinder.getConnectionPolicy(mDevice, null);
-
verify(mService).getConnectionPolicy(mDevice);
}
@@ -106,13 +103,13 @@ public class MapClientServiceBinderTest {
public void sendMessage_callsServiceMethod() {
Uri[] contacts = new Uri[] {};
String message = "test_message";
- mBinder.sendMessage(mDevice, contacts, message, null, null, null);
+ mBinder.sendMessage(mDevice, contacts, message, null, null, null);
verify(mService).sendMessage(mDevice, contacts, message, null, null);
}
@Test
- public void cleanUp_doesNotCrash() {
+ public void cleanup_doesNotCrash() {
mBinder.cleanup();
}
}
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 c75333efcf..66f04951ee 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/mapclient/MessageTest.java b/android/app/tests/unit/src/com/android/bluetooth/mapclient/MessageTest.java
index 2f95d563a4..967e5b209d 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/mapclient/MessageTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/mapclient/MessageTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/mapclient/MessagesFilterTest.java b/android/app/tests/unit/src/com/android/bluetooth/mapclient/MessagesFilterTest.java
index 12bcf80f3c..5433d67897 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/mapclient/MessagesFilterTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/mapclient/MessagesFilterTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 The Android Open Source Project
+ * Copyright (C) 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/mapclient/MessagesListingTest.java b/android/app/tests/unit/src/com/android/bluetooth/mapclient/MessagesListingTest.java
index 48ece843fe..ab6e7a46a4 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/mapclient/MessagesListingTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/mapclient/MessagesListingTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 The Android Open Source Project
+ * Copyright (C) 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.
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 3979e3cc60..2abea296e7 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/mapclient/RequestGetMessagesListingForOwnNumberTest.java b/android/app/tests/unit/src/com/android/bluetooth/mapclient/RequestGetMessagesListingForOwnNumberTest.java
index 9ca5a6e3b4..bd8bb8574c 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/mapclient/RequestGetMessagesListingForOwnNumberTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/mapclient/RequestGetMessagesListingForOwnNumberTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/mcp/McpServiceBinderTest.java b/android/app/tests/unit/src/com/android/bluetooth/mcp/McpServiceBinderTest.java
new file mode 100644
index 0000000000..dc21e810b8
--- /dev/null
+++ b/android/app/tests/unit/src/com/android/bluetooth/mcp/McpServiceBinderTest.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.bluetooth.mcp;
+
+import static com.android.bluetooth.TestUtils.MockitoRule;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.bluetooth.BluetoothDevice;
+import android.content.AttributionSource;
+
+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;
+
+/** Test cases for {@link McpServiceBinder} */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class McpServiceBinderTest {
+
+ @Rule public final MockitoRule mMockitoRule = new MockitoRule();
+
+ @Mock private McpService mService;
+
+ private AttributionSource mAttributionSource;
+ private McpServiceBinder mBinder;
+
+ @Before
+ public void setUp() throws Exception {
+ when(mService.isAvailable()).thenReturn(true);
+ mBinder = new McpServiceBinder(mService);
+ mAttributionSource = new AttributionSource.Builder(1).build();
+ }
+
+ @Test
+ public void setDeviceAuthorized() {
+ BluetoothDevice device = mock(BluetoothDevice.class);
+ boolean isAuthorized = true;
+
+ mBinder.setDeviceAuthorized(device, isAuthorized, mAttributionSource);
+ verify(mService).setDeviceAuthorized(device, isAuthorized);
+ }
+
+ @Test
+ public void cleanup_doesNotCrash() {
+ mBinder.cleanup();
+ }
+}
diff --git a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppBatchTest.java b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppBatchTest.java
index 4990c5315b..e3f764d2bc 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppBatchTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppBatchTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
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 59227bae0b..daa65ebba6 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
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 6b757ad437..b20858b647 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
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 5e56af0711..5e5d11ce4d 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
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 2481534d3c..b216680836 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 The Android Open Source Project
+ * Copyright (C) 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.
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 5378dc6f41..1e850d057b 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
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 58eca97965..91b1b0b65d 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 The Android Open Source Project
+ * Copyright (C) 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppReceiveFileInfoTest.java b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppReceiveFileInfoTest.java
index 07cea67691..3f74ac90d1 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppReceiveFileInfoTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppReceiveFileInfoTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
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 28ece7fcb3..0a144d7b35 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
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 4d991b5610..d76517320e 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
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 8055882546..a065757c01 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 The Android Open Source Project
+ * Copyright (C) 2018 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppShareInfoTest.java b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppShareInfoTest.java
index 26b987bb0b..212f1ffef7 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppShareInfoTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppShareInfoTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppTestUtils.java b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppTestUtils.java
index 3345530765..e1ca5e7e7e 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppTestUtils.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppTestUtils.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
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 5a268d1614..ece55f357e 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
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 c122b44579..f6c393909c 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
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 842a0aeacd..cadff94862 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -44,6 +44,7 @@ import android.content.pm.ResolveInfo;
import android.database.Cursor;
import android.net.Uri;
import android.os.ParcelFileDescriptor;
+import android.provider.Settings;
import androidx.test.platform.app.InstrumentationRegistry;
@@ -432,4 +433,22 @@ public class BluetoothOppUtilityTest {
assertWithMessage("Exception should not happen. " + e).fail();
}
}
+
+ @Test
+ public void grantPermissionToNearbyComponent() {
+ Uri originalUri = Uri.parse("content://test.provider/1");
+ Settings.Secure.putString(
+ mContext.getContentResolver(),
+ "nearby_sharing_component",
+ "com.example/.BComponent");
+ Context spiedContext = spy(new ContextWrapper(mContext));
+
+ BluetoothOppUtility.grantPermissionToNearbyComponent(spiedContext, List.of(originalUri));
+
+ verify(spiedContext)
+ .grantUriPermission(
+ eq("com.example"),
+ eq(originalUri),
+ eq(Intent.FLAG_GRANT_READ_URI_PERMISSION));
+ }
}
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 ddabada6bc..04843899fb 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
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 15763b79c3..1ba4881c90 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -35,75 +35,72 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
+/** Test cases for {@link PanServiceBinder} */
@SmallTest
@RunWith(AndroidJUnit4.class)
public class PanServiceBinderTest {
+
@Rule public final MockitoRule mMockitoRule = new MockitoRule();
@Mock private PanService mService;
private final BluetoothDevice mDevice = getTestDevice(64);
- PanService.BluetoothPanBinder mBinder;
+ private PanServiceBinder mBinder;
@Before
public void setUp() throws Exception {
- mBinder = new PanService.BluetoothPanBinder(mService);
+ mBinder = new PanServiceBinder(mService);
}
@Test
public void connect_callsServiceMethod() {
mBinder.connect(mDevice, null);
-
verify(mService).connect(mDevice);
}
@Test
public void disconnect_callsServiceMethod() {
mBinder.disconnect(mDevice, null);
-
verify(mService).disconnect(mDevice);
}
@Test
public void getConnectedDevices_callsServiceMethod() {
mBinder.getConnectedDevices(null);
-
verify(mService).getConnectedDevices();
}
@Test
public void getDevicesMatchingConnectionStates_callsServiceMethod() {
int[] states = new int[] {STATE_CONNECTED};
- mBinder.getDevicesMatchingConnectionStates(states, null);
+ mBinder.getDevicesMatchingConnectionStates(states, null);
verify(mService).getDevicesMatchingConnectionStates(states);
}
@Test
public void getConnectionState_callsServiceMethod() {
mBinder.getConnectionState(mDevice, null);
-
verify(mService).getConnectionState(mDevice);
}
@Test
public void setConnectionPolicy_callsServiceMethod() {
int connectionPolicy = CONNECTION_POLICY_ALLOWED;
- mBinder.setConnectionPolicy(mDevice, connectionPolicy, null);
+ mBinder.setConnectionPolicy(mDevice, connectionPolicy, null);
verify(mService).setConnectionPolicy(mDevice, connectionPolicy);
}
@Test
public void isTetheringOn_callsServiceMethod() {
mBinder.isTetheringOn(null);
-
verify(mService).isTetheringOn();
}
@Test
- public void cleanUp_doesNotCrash() {
+ public void cleanup_doesNotCrash() {
mBinder.cleanup();
}
}
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 f8e22122d6..1621909b73 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 The Android Open Source Project
+ * Copyright (C) 2018 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.
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 c781ca82ac..73aa0f015f 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
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 f57cbc2758..a95fbcc461 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
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 ed78e3239c..a833c6134b 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
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 becc52e836..2397f3897a 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -35,20 +35,22 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
+/** Test cases for {@link BluetoothPbapServiceBinder} */
@MediumTest
@RunWith(AndroidJUnit4.class)
public class BluetoothPbapServiceBinderTest {
+
@Rule public final MockitoRule mMockitoRule = new MockitoRule();
@Mock private BluetoothPbapService mService;
private final BluetoothDevice mDevice = getTestDevice(60);
- BluetoothPbapService.PbapBinder mBinder;
+ private BluetoothPbapServiceBinder mBinder;
@Before
public void setUp() {
- mBinder = new BluetoothPbapService.PbapBinder(mService);
+ mBinder = new BluetoothPbapServiceBinder(mService);
}
@Test
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 d3a4de5fed..e19ca130bf 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 The Android Open Source Project
+ * Copyright (C) 2018 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.
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 a2252796e3..4afce15b68 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
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 2f4760f451..df448082c2 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
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 b696cef960..e95e90088a 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
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 308a40b282..3b6034cd33 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
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 7245788429..9382902122 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
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 607bf253d4..c46ea24702 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2017 The Android Open Source Project
+ * Copyright (C) 2017 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.
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 b3669a14f6..376dcd9adf 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/FakeContactsProvider.java b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/FakeContactsProvider.java
index 356c26d2d0..36408dc7df 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/FakeContactsProvider.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/FakeContactsProvider.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 The Android Open Source Project
+ * Copyright (C) 2024 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapApplicationParametersTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapApplicationParametersTest.java
index 81c90a9ab3..8f8c076648 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapApplicationParametersTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapApplicationParametersTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 The Android Open Source Project
+ * Copyright (C) 2024 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientAccountAuthenticatorServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientAccountAuthenticatorServiceTest.java
index e25c542889..dfc7c322a5 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientAccountAuthenticatorServiceTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientAccountAuthenticatorServiceTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientAccountAuthenticatorTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientAccountAuthenticatorTest.java
index 237b3215cb..fce20be7ad 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientAccountAuthenticatorTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientAccountAuthenticatorTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientAccountManagerTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientAccountManagerTest.java
index a2b773fc03..e3ed3884a4 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientAccountManagerTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientAccountManagerTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 The Android Open Source Project
+ * Copyright (C) 2024 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.
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 d3ebddfa18..eef3517311 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientContactsStorageTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientContactsStorageTest.java
index ea515ec840..afd2c2a085 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientContactsStorageTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientContactsStorageTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 The Android Open Source Project
+ * Copyright (C) 2024 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientObexAuthenticatorTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientObexAuthenticatorTest.java
index 74265a31ae..45476f1b73 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientObexAuthenticatorTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientObexAuthenticatorTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientObexClientTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientObexClientTest.java
index 39a0e229fe..ef315042d2 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientObexClientTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientObexClientTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 The Android Open Source Project
+ * Copyright (C) 2024 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientObexTransportTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientObexTransportTest.java
index 29fc05c955..dfcc542467 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientObexTransportTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientObexTransportTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 The Android Open Source Project
+ * Copyright (C) 2024 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientBinderTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientServiceBinderTest.java
index aff8f250a7..94b51136dd 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientBinderTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientServiceBinderTest.java
@@ -47,29 +47,30 @@ import org.mockito.Mock;
import java.util.List;
+/** Test cases for {@link PbapClientServiceBinder} */
@MediumTest
@RunWith(AndroidJUnit4.class)
-public class PbapClientBinderTest {
+public class PbapClientServiceBinderTest {
@Rule public final MockitoRule mMockitoRule = new MockitoRule();
@Mock private PbapClientService mMockService;
private BluetoothDevice mTestDevice;
private AttributionSource mAttributionSource;
- private PbapClientBinder mPbapClientBinder;
+ private PbapClientServiceBinder mPbapClientServiceBinder;
@Before
public void setUp() throws Exception {
mTestDevice = getTestDevice(1);
mAttributionSource = new AttributionSource.Builder(1).build();
- mPbapClientBinder = new PbapClientBinder(mMockService);
+ mPbapClientServiceBinder = new PbapClientServiceBinder(mMockService);
}
@After
public void tearDown() throws Exception {
- if (mPbapClientBinder != null) {
- mPbapClientBinder.cleanup();
- mPbapClientBinder = null;
+ if (mPbapClientServiceBinder != null) {
+ mPbapClientServiceBinder.cleanup();
+ mPbapClientServiceBinder = null;
}
}
@@ -79,45 +80,46 @@ public class PbapClientBinderTest {
@Test
public void testConnect() {
- mPbapClientBinder.connect(mTestDevice, mAttributionSource);
+ mPbapClientServiceBinder.connect(mTestDevice, mAttributionSource);
verify(mMockService).connect(eq(mTestDevice));
}
@Test
public void testDisconnect() {
- mPbapClientBinder.disconnect(mTestDevice, mAttributionSource);
+ mPbapClientServiceBinder.disconnect(mTestDevice, mAttributionSource);
verify(mMockService).disconnect(eq(mTestDevice));
}
@Test
public void testGetConnectedDevices() {
- mPbapClientBinder.getConnectedDevices(mAttributionSource);
+ mPbapClientServiceBinder.getConnectedDevices(mAttributionSource);
verify(mMockService).getConnectedDevices();
}
@Test
public void testGetDevicesMatchingConnectionStates() {
int[] states = new int[] {STATE_CONNECTED};
- mPbapClientBinder.getDevicesMatchingConnectionStates(states, mAttributionSource);
+ mPbapClientServiceBinder.getDevicesMatchingConnectionStates(states, mAttributionSource);
verify(mMockService).getDevicesMatchingConnectionStates(eq(states));
}
@Test
public void testGetConnectionState() {
- mPbapClientBinder.getConnectionState(mTestDevice, mAttributionSource);
+ mPbapClientServiceBinder.getConnectionState(mTestDevice, mAttributionSource);
verify(mMockService).getConnectionState(eq(mTestDevice));
}
@Test
public void testSetConnectionPolicy() {
int connectionPolicy = CONNECTION_POLICY_ALLOWED;
- mPbapClientBinder.setConnectionPolicy(mTestDevice, connectionPolicy, mAttributionSource);
+ mPbapClientServiceBinder.setConnectionPolicy(
+ mTestDevice, connectionPolicy, mAttributionSource);
verify(mMockService).setConnectionPolicy(eq(mTestDevice), eq(connectionPolicy));
}
@Test
public void testGetConnectionPolicy() {
- mPbapClientBinder.getConnectionPolicy(mTestDevice, mAttributionSource);
+ mPbapClientServiceBinder.getConnectionPolicy(mTestDevice, mAttributionSource);
verify(mMockService).getConnectionPolicy(eq(mTestDevice));
}
@@ -127,52 +129,54 @@ public class PbapClientBinderTest {
@Test
public void testConnect_afterCleanup_returnsFalse() {
- mPbapClientBinder.cleanup();
- boolean result = mPbapClientBinder.connect(mTestDevice, mAttributionSource);
+ mPbapClientServiceBinder.cleanup();
+ boolean result = mPbapClientServiceBinder.connect(mTestDevice, mAttributionSource);
verify(mMockService, never()).connect(any(BluetoothDevice.class));
assertThat(result).isFalse();
}
@Test
public void testDisconnect_afterCleanup_returnsFalse() {
- mPbapClientBinder.cleanup();
- boolean result = mPbapClientBinder.disconnect(mTestDevice, mAttributionSource);
+ mPbapClientServiceBinder.cleanup();
+ boolean result = mPbapClientServiceBinder.disconnect(mTestDevice, mAttributionSource);
verify(mMockService, never()).disconnect(any(BluetoothDevice.class));
assertThat(result).isFalse();
}
@Test
public void testGetConnectedDevices_afterCleanup_returnsEmptyList() {
- mPbapClientBinder.cleanup();
- List<BluetoothDevice> devices = mPbapClientBinder.getConnectedDevices(mAttributionSource);
+ mPbapClientServiceBinder.cleanup();
+ List<BluetoothDevice> devices =
+ mPbapClientServiceBinder.getConnectedDevices(mAttributionSource);
verify(mMockService, never()).getConnectedDevices();
assertThat(devices).isEmpty();
}
@Test
public void testGetDevicesMatchingConnectionStates_afterCleanup_returnsEmptyList() {
- mPbapClientBinder.cleanup();
+ mPbapClientServiceBinder.cleanup();
int[] states = new int[] {STATE_CONNECTED};
List<BluetoothDevice> devices =
- mPbapClientBinder.getDevicesMatchingConnectionStates(states, mAttributionSource);
+ mPbapClientServiceBinder.getDevicesMatchingConnectionStates(
+ states, mAttributionSource);
verify(mMockService, never()).getDevicesMatchingConnectionStates(any(int[].class));
assertThat(devices).isEmpty();
}
@Test
public void testGetConnectionState_afterCleanup_returnsDisconnected() {
- mPbapClientBinder.cleanup();
- int state = mPbapClientBinder.getConnectionState(mTestDevice, mAttributionSource);
+ mPbapClientServiceBinder.cleanup();
+ int state = mPbapClientServiceBinder.getConnectionState(mTestDevice, mAttributionSource);
verify(mMockService, never()).getConnectionState(any(BluetoothDevice.class));
assertThat(state).isEqualTo(STATE_DISCONNECTED);
}
@Test
public void testSetConnectionPolicy_afterCleanup_returnsFalse() {
- mPbapClientBinder.cleanup();
+ mPbapClientServiceBinder.cleanup();
int connectionPolicy = CONNECTION_POLICY_ALLOWED;
boolean result =
- mPbapClientBinder.setConnectionPolicy(
+ mPbapClientServiceBinder.setConnectionPolicy(
mTestDevice, connectionPolicy, mAttributionSource);
verify(mMockService, never()).setConnectionPolicy(any(BluetoothDevice.class), anyInt());
assertThat(result).isFalse();
@@ -180,8 +184,8 @@ public class PbapClientBinderTest {
@Test
public void testGetConnectionPolicy_afterCleanup_returnsUnknown() {
- mPbapClientBinder.cleanup();
- int result = mPbapClientBinder.getConnectionPolicy(mTestDevice, mAttributionSource);
+ mPbapClientServiceBinder.cleanup();
+ int result = mPbapClientServiceBinder.getConnectionPolicy(mTestDevice, mAttributionSource);
verify(mMockService, never()).getConnectionPolicy(any(BluetoothDevice.class));
assertThat(result).isEqualTo(CONNECTION_POLICY_UNKNOWN);
}
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 35196f14f2..bf3014a7ac 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 The Android Open Source Project
+ * Copyright (C) 2018 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientSocketTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientSocketTest.java
index a3380b177b..64f1979437 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientSocketTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientSocketTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 The Android Open Source Project
+ * Copyright (C) 2024 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientStateMachineOldTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientStateMachineOldTest.java
index 3518b2d418..73c1722e75 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientStateMachineOldTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientStateMachineOldTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 The Android Open Source Project
+ * Copyright (C) 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.
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 0f1550d868..d9b8bef9d4 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 The Android Open Source Project
+ * Copyright (C) 2024 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapPhonebookMetadataTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapPhonebookMetadataTest.java
index cdd57f8a9c..2abafedf77 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapPhonebookMetadataTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapPhonebookMetadataTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 The Android Open Source Project
+ * Copyright (C) 2024 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapPhonebookTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapPhonebookTest.java
index 994dccf85a..5c24a9f794 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapPhonebookTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapPhonebookTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 The Android Open Source Project
+ * Copyright (C) 2024 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapSdpRecordTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapSdpRecordTest.java
index 7b3189db16..3248d6e9db 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapSdpRecordTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapSdpRecordTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 The Android Open Source Project
+ * Copyright (C) 2024 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PhonebookPullRequestTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PhonebookPullRequestTest.java
index d0e462ca66..10526bac41 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PhonebookPullRequestTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PhonebookPullRequestTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/RequestPullPhonebookMetadataTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/RequestPullPhonebookMetadataTest.java
index bdad362075..2e404f9614 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/RequestPullPhonebookMetadataTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/RequestPullPhonebookMetadataTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/RequestPullPhonebookTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/RequestPullPhonebookTest.java
index 55eb76ab67..551d3e3d2f 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/RequestPullPhonebookTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/RequestPullPhonebookTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/Utils.java b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/Utils.java
index 39bbd25746..d390746a02 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/Utils.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/Utils.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 The Android Open Source Project
+ * Copyright (C) 2024 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/sap/SapMessageTest.java b/android/app/tests/unit/src/com/android/bluetooth/sap/SapMessageTest.java
index eab7b0f84a..174e71a954 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/sap/SapMessageTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/sap/SapMessageTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
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 04d4238131..5d30fa6e93 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
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 d2e6ea5d03..80983b2eef 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
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 3bed89bda3..69d6434ff2 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/sap/SapServiceBinderTest.java b/android/app/tests/unit/src/com/android/bluetooth/sap/SapServiceBinderTest.java
new file mode 100644
index 0000000000..10d1a092e0
--- /dev/null
+++ b/android/app/tests/unit/src/com/android/bluetooth/sap/SapServiceBinderTest.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.bluetooth.sap;
+
+import static android.bluetooth.BluetoothProfile.STATE_CONNECTED;
+import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTED;
+
+import static com.android.bluetooth.TestUtils.MockitoRule;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.bluetooth.BluetoothDevice;
+import android.content.AttributionSource;
+
+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;
+
+/** Test cases for {@link SapServiceBinder} */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class SapServiceBinderTest {
+
+ @Rule public final MockitoRule mMockitoRule = new MockitoRule();
+
+ @Mock private SapService mService;
+
+ private AttributionSource mAttributionSource;
+ private SapServiceBinder mBinder;
+
+ @Before
+ public void setUp() throws Exception {
+ when(mService.isAvailable()).thenReturn(true);
+ mBinder = new SapServiceBinder(mService);
+ mAttributionSource = new AttributionSource.Builder(1).build();
+ }
+
+ @Test
+ public void getState() {
+ mBinder.getState(mAttributionSource);
+ verify(mService).getState();
+ }
+
+ @Test
+ public void getClient() {
+ mBinder.getClient(mAttributionSource);
+ // times(2) due to the Log
+ verify(mService, times(2)).getRemoteDevice();
+ }
+
+ @Test
+ public void isConnected() {
+ BluetoothDevice device = mock(BluetoothDevice.class);
+
+ mBinder.isConnected(device, mAttributionSource);
+ verify(mService).getConnectionState(device);
+ }
+
+ @Test
+ public void disconnect() {
+ BluetoothDevice device = mock(BluetoothDevice.class);
+
+ mBinder.disconnect(device, mAttributionSource);
+ verify(mService).disconnect(device);
+ }
+
+ @Test
+ public void getConnectedDevices() {
+ mBinder.getConnectedDevices(mAttributionSource);
+ verify(mService).getConnectedDevices();
+ }
+
+ @Test
+ public void getDevicesMatchingConnectionStates() {
+ int[] states = new int[] {STATE_CONNECTED, STATE_DISCONNECTED};
+
+ mBinder.getDevicesMatchingConnectionStates(states, mAttributionSource);
+ verify(mService).getDevicesMatchingConnectionStates(states);
+ }
+
+ @Test
+ public void getConnectionState() {
+ BluetoothDevice device = mock(BluetoothDevice.class);
+
+ mBinder.getConnectionState(device, mAttributionSource);
+ verify(mService).getConnectionState(device);
+ }
+
+ @Test
+ public void setConnectionPolicy() {
+ BluetoothDevice device = mock(BluetoothDevice.class);
+ int connectionPolicy = 1;
+
+ mBinder.setConnectionPolicy(device, connectionPolicy, mAttributionSource);
+ verify(mService).setConnectionPolicy(device, connectionPolicy);
+ }
+
+ @Test
+ public void getConnectionPolicy() {
+ BluetoothDevice device = mock(BluetoothDevice.class);
+
+ mBinder.getConnectionPolicy(device, mAttributionSource);
+ verify(mService).getConnectionPolicy(device);
+ }
+
+ @Test
+ public void cleanup_doesNotCrash() {
+ mBinder.cleanup();
+ }
+}
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 d6336bcb34..06d41b2db8 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 The Android Open Source Project
+ * Copyright (C) 2018 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.
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 c9c3c238e2..4e5042bad6 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 The Android Open Source Project
+ * Copyright (C) 2018 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/tbs/TbsServiceBinderTest.java b/android/app/tests/unit/src/com/android/bluetooth/tbs/TbsServiceBinderTest.java
new file mode 100644
index 0000000000..7758d101b1
--- /dev/null
+++ b/android/app/tests/unit/src/com/android/bluetooth/tbs/TbsServiceBinderTest.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.bluetooth.tbs;
+
+import static com.android.bluetooth.TestUtils.MockitoRule;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.bluetooth.BluetoothLeCall;
+import android.bluetooth.IBluetoothLeCallControlCallback;
+import android.content.AttributionSource;
+import android.os.ParcelUuid;
+
+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 java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+/** Test cases for {@link TbsServiceBinder} */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class TbsServiceBinderTest {
+
+ @Rule public final MockitoRule mMockitoRule = new MockitoRule();
+
+ @Mock private TbsService mService;
+
+ private AttributionSource mAttributionSource;
+ private TbsServiceBinder mBinder;
+
+ @Before
+ public void setUp() throws Exception {
+ when(mService.isAvailable()).thenReturn(true);
+ mBinder = new TbsServiceBinder(mService);
+ mAttributionSource = new AttributionSource.Builder(1).build();
+ }
+
+ @Test
+ public void registerBearer() {
+ String token = "token";
+ IBluetoothLeCallControlCallback callback = mock(IBluetoothLeCallControlCallback.class);
+ String uci = "uci";
+ List<String> uriSchemes = new ArrayList<>();
+ int capabilities = 1;
+ String providerName = "providerName";
+ int technology = 2;
+
+ mBinder.registerBearer(
+ token,
+ callback,
+ uci,
+ uriSchemes,
+ capabilities,
+ providerName,
+ technology,
+ mAttributionSource);
+ verify(mService)
+ .registerBearer(
+ token, callback, uci, uriSchemes, capabilities, providerName, technology);
+ }
+
+ @Test
+ public void unregisterBearer() {
+ String token = "token";
+
+ mBinder.unregisterBearer(token, mAttributionSource);
+ verify(mService).unregisterBearer(token);
+ }
+
+ @Test
+ public void requestResult() {
+ int ccid = 1;
+ int requestId = 2;
+ int result = 3;
+
+ mBinder.requestResult(ccid, requestId, result, mAttributionSource);
+ verify(mService).requestResult(ccid, requestId, result);
+ }
+
+ @Test
+ public void callAdded() {
+ int ccid = 1;
+ BluetoothLeCall call = mock(BluetoothLeCall.class);
+
+ mBinder.callAdded(ccid, call, mAttributionSource);
+ verify(mService).callAdded(ccid, call);
+ }
+
+ @Test
+ public void callRemoved() {
+ int ccid = 1;
+ UUID callId = UUID.randomUUID();
+ int reason = 2;
+
+ mBinder.callRemoved(ccid, new ParcelUuid(callId), reason, mAttributionSource);
+ verify(mService).callRemoved(ccid, callId, reason);
+ }
+
+ @Test
+ public void callStateChanged() {
+ int ccid = 1;
+ UUID callId = UUID.randomUUID();
+ int state = 2;
+
+ mBinder.callStateChanged(ccid, new ParcelUuid(callId), state, mAttributionSource);
+ verify(mService).callStateChanged(ccid, callId, state);
+ }
+
+ @Test
+ public void currentCallsList() {
+ int ccid = 1;
+ List<BluetoothLeCall> calls = new ArrayList<>();
+
+ mBinder.currentCallsList(ccid, calls, mAttributionSource);
+ verify(mService).currentCallsList(ccid, calls);
+ }
+
+ @Test
+ public void cleanup_doesNotCrash() {
+ mBinder.cleanup();
+ }
+}
diff --git a/android/app/tests/unit/src/com/android/bluetooth/telephony/BluetoothCallTest.java b/android/app/tests/unit/src/com/android/bluetooth/telephony/BluetoothCallTest.java
index 884b914a4f..441ac2b603 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/telephony/BluetoothCallTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/telephony/BluetoothCallTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlNativeCallbackTest.java b/android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlNativeCallbackTest.java
index 4045cb9bfb..e474775f88 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlNativeCallbackTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlNativeCallbackTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 The Android Open Source Project
+ * Copyright (C) 2024 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.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlServiceBinderTest.java b/android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlServiceBinderTest.java
new file mode 100644
index 0000000000..32296381c8
--- /dev/null
+++ b/android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlServiceBinderTest.java
@@ -0,0 +1,294 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.bluetooth.vc;
+
+import static android.bluetooth.BluetoothProfile.STATE_CONNECTED;
+
+import static com.android.bluetooth.TestUtils.MockitoRule;
+import static com.android.bluetooth.TestUtils.getTestDevice;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.IAudioInputCallback;
+import android.content.AttributionSource;
+
+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;
+
+/** Test cases for {@link VolumeControlServiceBinder} */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class VolumeControlServiceBinderTest {
+
+ @Rule public final MockitoRule mMockitoRule = new MockitoRule();
+
+ @Mock private VolumeControlService mService;
+
+ private final BluetoothDevice mDevice = getTestDevice(25);
+
+ private AttributionSource mAttributionSource;
+ private VolumeControlServiceBinder mBinder;
+
+ @Before
+ public void setUp() throws Exception {
+ when(mService.isAvailable()).thenReturn(true);
+ mBinder = new VolumeControlServiceBinder(mService);
+ mAttributionSource = new AttributionSource.Builder(1).build();
+ }
+
+ @Test
+ public void getConnectedDevices() {
+ mBinder.getConnectedDevices(mAttributionSource);
+ verify(mService).getConnectedDevices();
+ }
+
+ @Test
+ public void getDevicesMatchingConnectionStates() {
+ int[] states = new int[] {STATE_CONNECTED};
+
+ mBinder.getDevicesMatchingConnectionStates(states, mAttributionSource);
+ verify(mService).getDevicesMatchingConnectionStates(states);
+ }
+
+ @Test
+ public void getConnectionState() {
+ mBinder.getConnectionState(mDevice, mAttributionSource);
+ verify(mService).getConnectionState(mDevice);
+ }
+
+ @Test
+ public void setConnectionPolicy() {
+ int connectionPolicy = 1;
+
+ mBinder.setConnectionPolicy(mDevice, connectionPolicy, mAttributionSource);
+ verify(mService).setConnectionPolicy(mDevice, connectionPolicy);
+ }
+
+ @Test
+ public void getConnectionPolicy() {
+ mBinder.getConnectionPolicy(mDevice, mAttributionSource);
+ verify(mService).getConnectionPolicy(mDevice);
+ }
+
+ @Test
+ public void isVolumeOffsetAvailable() {
+ mBinder.isVolumeOffsetAvailable(mDevice, mAttributionSource);
+ verify(mService).isVolumeOffsetAvailable(mDevice);
+ }
+
+ @Test
+ public void getNumberOfVolumeOffsetInstances() {
+ mBinder.getNumberOfVolumeOffsetInstances(mDevice, mAttributionSource);
+ verify(mService).getNumberOfVolumeOffsetInstances(mDevice);
+ }
+
+ @Test
+ public void setVolumeOffset() {
+ int instanceId = 1;
+ int volumeOffset = 2;
+
+ mBinder.setVolumeOffset(mDevice, instanceId, volumeOffset, mAttributionSource);
+ verify(mService).setVolumeOffset(mDevice, instanceId, volumeOffset);
+ }
+
+ @Test
+ public void setDeviceVolume() {
+ int volume = 1;
+ boolean isGroupOp = true;
+
+ mBinder.setDeviceVolume(mDevice, volume, isGroupOp, mAttributionSource);
+ verify(mService).setDeviceVolume(mDevice, volume, isGroupOp);
+ }
+
+ @Test
+ public void setGroupVolume() {
+ int groupId = 1;
+ int volume = 2;
+
+ mBinder.setGroupVolume(groupId, volume, mAttributionSource);
+ verify(mService).setGroupVolume(groupId, volume);
+ }
+
+ @Test
+ public void getGroupVolume() {
+ int groupId = 1;
+
+ mBinder.getGroupVolume(groupId, mAttributionSource);
+ verify(mService).getGroupVolume(groupId);
+ }
+
+ @Test
+ public void setGroupActive() {
+ int groupId = 1;
+ boolean active = true;
+
+ mBinder.setGroupActive(groupId, active, mAttributionSource);
+ verify(mService).setGroupActive(groupId, active);
+ }
+
+ @Test
+ public void mute() {
+ mBinder.mute(mDevice, mAttributionSource);
+ verify(mService).mute(mDevice);
+ }
+
+ @Test
+ public void muteGroup() {
+ int groupId = 1;
+ mBinder.muteGroup(groupId, mAttributionSource);
+ verify(mService).muteGroup(groupId);
+ }
+
+ @Test
+ public void unmute() {
+ mBinder.unmute(mDevice, mAttributionSource);
+ verify(mService).unmute(mDevice);
+ }
+
+ @Test
+ public void unmuteGroup() {
+ int groupId = 1;
+
+ mBinder.unmuteGroup(groupId, mAttributionSource);
+ verify(mService).unmuteGroup(groupId);
+ }
+
+ @Test
+ public void getNumberOfAudioInputControlServices() {
+ mBinder.getNumberOfAudioInputControlServices(mAttributionSource, mDevice);
+ }
+
+ @Test
+ public void registerAudioInputControlCallback() {
+ int instanceId = 1;
+ IAudioInputCallback callback = mock(IAudioInputCallback.class);
+
+ mBinder.registerAudioInputControlCallback(
+ mAttributionSource, mDevice, instanceId, callback);
+ }
+
+ @Test
+ public void unregisterAudioInputControlCallback() {
+ int instanceId = 1;
+ IAudioInputCallback callback = mock(IAudioInputCallback.class);
+
+ mBinder.unregisterAudioInputControlCallback(
+ mAttributionSource, mDevice, instanceId, callback);
+ }
+
+ @Test
+ public void getAudioInputGainSettingUnit() {
+ int instanceId = 1;
+ mBinder.getAudioInputGainSettingUnit(mAttributionSource, mDevice, instanceId);
+ }
+
+ @Test
+ public void getAudioInputGainSettingMin() {
+ int instanceId = 1;
+ mBinder.getAudioInputGainSettingMin(mAttributionSource, mDevice, instanceId);
+ }
+
+ @Test
+ public void getAudioInputGainSettingMax() {
+ int instanceId = 1;
+ mBinder.getAudioInputGainSettingMax(mAttributionSource, mDevice, instanceId);
+ }
+
+ @Test
+ public void getAudioInputDescription() {
+ int instanceId = 1;
+ mBinder.getAudioInputDescription(mAttributionSource, mDevice, instanceId);
+ }
+
+ @Test
+ public void isAudioInputDescriptionWritable() {
+ int instanceId = 1;
+ mBinder.isAudioInputDescriptionWritable(mAttributionSource, mDevice, instanceId);
+ }
+
+ @Test
+ public void setAudioInputDescription() {
+ int instanceId = 1;
+ String description = "test";
+ mBinder.setAudioInputDescription(mAttributionSource, mDevice, instanceId, description);
+ }
+
+ @Test
+ public void getAudioInputStatus() {
+ int instanceId = 1;
+ mBinder.getAudioInputStatus(mAttributionSource, mDevice, instanceId);
+ }
+
+ @Test
+ public void getAudioInputType() {
+ int instanceId = 1;
+ mBinder.getAudioInputType(mAttributionSource, mDevice, instanceId);
+ }
+
+ @Test
+ public void getAudioInputGainSetting() {
+ int instanceId = 1;
+ mBinder.getAudioInputGainSetting(mAttributionSource, mDevice, instanceId);
+ }
+
+ @Test
+ public void setAudioInputGainSetting() {
+ int instanceId = 1;
+ int gainSetting = 2;
+ mBinder.setAudioInputGainSetting(mAttributionSource, mDevice, instanceId, gainSetting);
+ }
+
+ @Test
+ public void getAudioInputGainMode() {
+ int instanceId = 1;
+ mBinder.getAudioInputGainMode(mAttributionSource, mDevice, instanceId);
+ }
+
+ @Test
+ public void setAudioInputGainMode() {
+ int instanceId = 1;
+ int gainMode = 2;
+ mBinder.setAudioInputGainMode(mAttributionSource, mDevice, instanceId, gainMode);
+ }
+
+ @Test
+ public void getAudioInputMute() {
+ int instanceId = 1;
+ mBinder.getAudioInputMute(mAttributionSource, mDevice, instanceId);
+ }
+
+ @Test
+ public void setAudioInputMute() {
+ int instanceId = 1;
+ int mute = 2;
+ mBinder.setAudioInputMute(mAttributionSource, mDevice, instanceId, mute);
+ }
+
+ @Test
+ public void cleanup_doesNotCrash() {
+ mBinder.cleanup();
+ }
+}
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 35d8ee3ce1..9412ebfe40 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
@@ -128,7 +128,7 @@ public class VolumeControlServiceTest {
private AttributionSource mAttributionSource;
private VolumeControlService mService;
- private VolumeControlService.BluetoothVolumeControlBinder mBinder;
+ private VolumeControlServiceBinder mBinder;
private InOrder mInOrder;
private TestLooper mLooper;
@@ -174,7 +174,7 @@ public class VolumeControlServiceTest {
mService.setAvailable(true);
mService.mFactory = mServiceFactory;
- mBinder = (VolumeControlService.BluetoothVolumeControlBinder) mService.initBinder();
+ mBinder = (VolumeControlServiceBinder) mService.initBinder();
}
@After
diff --git a/android/leaudio/app/.classpath b/android/leaudio/app/.classpath
index 4a04201ca2..bbe97e501d 100644
--- a/android/leaudio/app/.classpath
+++ b/android/leaudio/app/.classpath
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
- <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11/"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-17/"/>
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/>
<classpathentry kind="output" path="bin/default"/>
</classpath>
diff --git a/android/leaudio/gradle/wrapper/gradle-wrapper.jar b/android/leaudio/gradle/wrapper/gradle-wrapper.jar
index f6b961fd5a..41d9927a4d 100644
--- a/android/leaudio/gradle/wrapper/gradle-wrapper.jar
+++ b/android/leaudio/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/android/leaudio/gradle/wrapper/gradle-wrapper.properties b/android/leaudio/gradle/wrapper/gradle-wrapper.properties
index bd98b5dbe3..aa991fceae 100644
--- a/android/leaudio/gradle/wrapper/gradle-wrapper.properties
+++ b/android/leaudio/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,5 @@
-#Thu Oct 15 09:37:54 CEST 2020
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip
diff --git a/android/leaudio/gradlew b/android/leaudio/gradlew
index cccdd3d517..1b6c787337 100755
--- a/android/leaudio/gradlew
+++ b/android/leaudio/gradlew
@@ -1,78 +1,129 @@
-#!/usr/bin/env sh
+#!/bin/sh
+
+#
+# Copyright © 2015-2021 the original authors.
+#
+# 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
+#
+# https://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.
+#
##############################################################################
-##
-## Gradle start up script for UN*X
-##
+#
+# Gradle start up script for POSIX generated by Gradle.
+#
+# Important for running:
+#
+# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
+# noncompliant, but you have some other compliant shell such as ksh or
+# bash, then to run this script, type that shell name before the whole
+# command line, like:
+#
+# ksh Gradle
+#
+# Busybox and similar reduced shells will NOT work, because this script
+# requires all of these POSIX shell features:
+# * functions;
+# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
+# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
+# * compound commands having a testable exit status, especially «case»;
+# * various built-in commands including «command», «set», and «ulimit».
+#
+# Important for patching:
+#
+# (2) This script targets any POSIX shell, so it avoids extensions provided
+# by Bash, Ksh, etc; in particular arrays are avoided.
+#
+# The "traditional" practice of packing multiple parameters into a
+# space-separated string is a well documented source of bugs and security
+# problems, so this is (mostly) avoided, by progressively accumulating
+# options in "$@", and eventually passing that to Java.
+#
+# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
+# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
+# see the in-line comments for details.
+#
+# There are tweaks for specific operating systems such as AIX, CygWin,
+# Darwin, MinGW, and NonStop.
+#
+# (3) This script is generated from the Groovy template
+# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+# within the Gradle project.
+#
+# You can find Gradle at https://github.com/gradle/gradle/.
+#
##############################################################################
# Attempt to set APP_HOME
+
# Resolve links: $0 may be a link
-PRG="$0"
-# Need this for relative symlinks.
-while [ -h "$PRG" ] ; do
- ls=`ls -ld "$PRG"`
- link=`expr "$ls" : '.*-> \(.*\)$'`
- if expr "$link" : '/.*' > /dev/null; then
- PRG="$link"
- else
- PRG=`dirname "$PRG"`"/$link"
- fi
+app_path=$0
+
+# Need this for daisy-chained symlinks.
+while
+ APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
+ [ -h "$app_path" ]
+do
+ ls=$( ls -ld "$app_path" )
+ link=${ls#*' -> '}
+ case $link in #(
+ /*) app_path=$link ;; #(
+ *) app_path=$APP_HOME$link ;;
+ esac
done
-SAVED="`pwd`"
-cd "`dirname \"$PRG\"`/" >/dev/null
-APP_HOME="`pwd -P`"
-cd "$SAVED" >/dev/null
+
+APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
APP_NAME="Gradle"
-APP_BASE_NAME=`basename "$0"`
+APP_BASE_NAME=${0##*/}
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-DEFAULT_JVM_OPTS=""
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
-MAX_FD="maximum"
+MAX_FD=maximum
warn () {
echo "$*"
-}
+} >&2
die () {
echo
echo "$*"
echo
exit 1
-}
+} >&2
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
-case "`uname`" in
- CYGWIN* )
- cygwin=true
- ;;
- Darwin* )
- darwin=true
- ;;
- MINGW* )
- msys=true
- ;;
- NONSTOP* )
- nonstop=true
- ;;
+case "$( uname )" in #(
+ CYGWIN* ) cygwin=true ;; #(
+ Darwin* ) darwin=true ;; #(
+ MSYS* | MINGW* ) msys=true ;; #(
+ NONSTOP* ) nonstop=true ;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
- JAVACMD="$JAVA_HOME/jre/sh/java"
+ JAVACMD=$JAVA_HOME/jre/sh/java
else
- JAVACMD="$JAVA_HOME/bin/java"
+ JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
@@ -81,7 +132,7 @@ Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
- JAVACMD="java"
+ JAVACMD=java
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
@@ -89,84 +140,95 @@ location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
-if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
- MAX_FD_LIMIT=`ulimit -H -n`
- if [ $? -eq 0 ] ; then
- if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
- MAX_FD="$MAX_FD_LIMIT"
- fi
- ulimit -n $MAX_FD
- if [ $? -ne 0 ] ; then
- warn "Could not set maximum file descriptor limit: $MAX_FD"
- fi
- else
- warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
- fi
+if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
+ case $MAX_FD in #(
+ max*)
+ MAX_FD=$( ulimit -H -n ) ||
+ warn "Could not query maximum file descriptor limit"
+ esac
+ case $MAX_FD in #(
+ '' | soft) :;; #(
+ *)
+ ulimit -n "$MAX_FD" ||
+ warn "Could not set maximum file descriptor limit to $MAX_FD"
+ esac
fi
-# For Darwin, add options to specify how the application appears in the dock
-if $darwin; then
- GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
-fi
+# Collect all arguments for the java command, stacking in reverse order:
+# * args from the command line
+# * the main class name
+# * -classpath
+# * -D...appname settings
+# * --module-path (only if needed)
+# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if "$cygwin" || "$msys" ; then
+ APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
+ CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
+
+ JAVACMD=$( cygpath --unix "$JAVACMD" )
-# For Cygwin, switch paths to Windows format before running java
-if $cygwin ; then
- APP_HOME=`cygpath --path --mixed "$APP_HOME"`
- CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
- JAVACMD=`cygpath --unix "$JAVACMD"`
-
- # We build the pattern for arguments to be converted via cygpath
- ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
- SEP=""
- for dir in $ROOTDIRSRAW ; do
- ROOTDIRS="$ROOTDIRS$SEP$dir"
- SEP="|"
- done
- OURCYGPATTERN="(^($ROOTDIRS))"
- # Add a user-defined pattern to the cygpath arguments
- if [ "$GRADLE_CYGPATTERN" != "" ] ; then
- OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
- fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
- i=0
- for arg in "$@" ; do
- CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
- CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
-
- if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
- eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
- else
- eval `echo args$i`="\"$arg\""
+ for arg do
+ if
+ case $arg in #(
+ -*) false ;; # don't mess with options #(
+ /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
+ [ -e "$t" ] ;; #(
+ *) false ;;
+ esac
+ then
+ arg=$( cygpath --path --ignore --mixed "$arg" )
fi
- i=$((i+1))
+ # Roll the args list around exactly as many times as the number of
+ # args, so each arg winds up back in the position where it started, but
+ # possibly modified.
+ #
+ # NB: a `for` loop captures its iteration list before it begins, so
+ # changing the positional parameters here affects neither the number of
+ # iterations, nor the values presented in `arg`.
+ shift # remove old arg
+ set -- "$@" "$arg" # push replacement arg
done
- case $i in
- (0) set -- ;;
- (1) set -- "$args0" ;;
- (2) set -- "$args0" "$args1" ;;
- (3) set -- "$args0" "$args1" "$args2" ;;
- (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
- (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
- (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
- (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
- (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
- (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
- esac
fi
-# Escape application args
-save () {
- for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
- echo " "
-}
-APP_ARGS=$(save "$@")
-
-# Collect all arguments for the java command, following the shell quoting and substitution rules
-eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
-
-# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
-if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
- cd "$(dirname "$0")"
-fi
+# Collect all arguments for the java command;
+# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
+# shell script including quotes and variable substitutions, so put them in
+# double quotes to make sure that they get re-expanded; and
+# * put everything else in single quotes, so that it's not re-expanded.
+
+set -- \
+ "-Dorg.gradle.appname=$APP_BASE_NAME" \
+ -classpath "$CLASSPATH" \
+ org.gradle.wrapper.GradleWrapperMain \
+ "$@"
+
+# Use "xargs" to parse quoted args.
+#
+# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
+#
+# In Bash we could simply go:
+#
+# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
+# set -- "${ARGS[@]}" "$@"
+#
+# but POSIX shell has neither arrays nor command substitution, so instead we
+# post-process each arg (as a line of input to sed) to backslash-escape any
+# character that might be a shell metacharacter, then use eval to reverse
+# that process (while maintaining the separation between arguments), and wrap
+# the whole thing up as a single "set" statement.
+#
+# This will of course break if any of these variables contains a newline or
+# an unmatched quote.
+#
+
+eval "set -- $(
+ printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
+ xargs -n1 |
+ sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
+ tr '\n' ' '
+ )" '"$@"'
exec "$JAVACMD" "$@"
diff --git a/android/leaudio/gradlew.bat b/android/leaudio/gradlew.bat
index e95643d6a2..ac1b06f938 100644
--- a/android/leaudio/gradlew.bat
+++ b/android/leaudio/gradlew.bat
@@ -1,3 +1,19 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@@ -13,15 +29,18 @@ if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-set DEFAULT_JVM_OPTS=
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
-if "%ERRORLEVEL%" == "0" goto init
+if "%ERRORLEVEL%" == "0" goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
@@ -35,7 +54,7 @@ goto fail
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
-if exist "%JAVA_EXE%" goto init
+if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
@@ -45,28 +64,14 @@ echo location of your Java installation.
goto fail
-:init
-@rem Get command-line arguments, handling Windows variants
-
-if not "%OS%" == "Windows_NT" goto win9xME_args
-
-:win9xME_args
-@rem Slurp the command line arguments.
-set CMD_LINE_ARGS=
-set _SKIP=2
-
-:win9xME_args_slurp
-if "x%~1" == "x" goto execute
-
-set CMD_LINE_ARGS=%*
-
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
@rem Execute Gradle
-"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
diff --git a/android/pandora/server/configs/pts_bot_tests_config.json b/android/pandora/server/configs/pts_bot_tests_config.json
index e80e123437..023cb94544 100644
--- a/android/pandora/server/configs/pts_bot_tests_config.json
+++ b/android/pandora/server/configs/pts_bot_tests_config.json
@@ -24,7 +24,6 @@
"A2DP/SNK/CC/BV-08-I",
"A2DP/SNK/REL/BV-01-I",
"A2DP/SNK/REL/BV-02-I",
- "A2DP/SNK/SDP/BV-02-I",
"A2DP/SNK/SET/BV-01-I",
"A2DP/SNK/SET/BV-02-I",
"A2DP/SNK/SET/BV-03-I",
@@ -44,7 +43,6 @@
"A2DP/SRC/CC/BV-09-I",
"A2DP/SRC/REL/BV-01-I",
"A2DP/SRC/REL/BV-02-I",
- "A2DP/SRC/SDP/BV-01-I",
"A2DP/SRC/SET/BV-01-I",
"A2DP/SRC/SET/BV-02-I",
"A2DP/SRC/SET/BV-03-I",
@@ -735,6 +733,7 @@
],
"skip": [
"A2DP/SNK/AVP/BI-07-C",
+ "A2DP/SNK/SDP/BV-02-I",
"A2DP/SNK/SET/BV-04-I",
"A2DP/SNK/SET/BV-06-I",
"A2DP/SNK/SUS/BV-02-I",
@@ -742,6 +741,7 @@
"A2DP/SRC/AS/BV-03-I",
"A2DP/SRC/AS/BV-04-I",
"A2DP/SRC/CC/BV-10-I",
+ "A2DP/SRC/SDP/BV-01-I",
"A2DP/SRC/SET/BV-05-I",
"A2DP/SRC/SET/BV-06-I",
"A2DP/SRC/SUS/BV-02-I",
diff --git a/android/pandora/test/main.py b/android/pandora/test/main.py
index d5c5da0bad..7e49321932 100644
--- a/android/pandora/test/main.py
+++ b/android/pandora/test/main.py
@@ -25,6 +25,7 @@ import avatar.cases.security_test
import gatt_test
import hap_test
import hfpclient_test
+import rfcomm_test
import sdp_test
from pairing import _test_class_list as _pairing_test_class_list
@@ -81,6 +82,7 @@ _TEST_CLASSES_LIST = [
hap_test.HapTest,
asha_test.AshaTest,
hfpclient_test.HfpClientTest,
+ rfcomm_test.RfcommTest,
] + _pairing_test_class_list
diff --git a/android/pandora/test/rfcomm_test.py b/android/pandora/test/rfcomm_test.py
new file mode 100644
index 0000000000..4409b02e25
--- /dev/null
+++ b/android/pandora/test/rfcomm_test.py
@@ -0,0 +1,110 @@
+# Copyright 2025 Google LLC
+#
+# 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
+#
+# https://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.
+
+import asyncio
+import avatar
+import grpc
+import logging
+
+from avatar import PandoraDevices
+from avatar.aio import asynchronous
+from avatar.pandora_client import BumblePandoraClient, PandoraClient
+from bumble.rfcomm import Server
+from bumble_experimental.rfcomm import RFCOMMService
+from mobly import base_test, test_runner
+from mobly.asserts import assert_equal # type: ignore
+from mobly.asserts import assert_in # type: ignore
+from mobly.asserts import assert_is_not_none # type: ignore
+from mobly.asserts import fail # type: ignore
+from pandora_experimental.rfcomm_grpc_aio import RFCOMM
+from pandora_experimental.rfcomm_pb2 import (
+ AcceptConnectionRequest,
+ RxRequest,
+ StartServerRequest,
+ StopServerRequest,
+ TxRequest,
+)
+from typing import Optional, Tuple
+
+SERIAL_PORT_UUID = "00001101-0000-1000-8000-00805F9B34FB"
+TEST_SERVER_NAME = "RFCOMM-Server"
+
+
+class RfcommTest(base_test.BaseTestClass):
+ devices: Optional[PandoraDevices] = None
+ dut: PandoraClient
+ ref: BumblePandoraClient
+
+ def setup_class(self) -> None:
+ self.devices = PandoraDevices(self)
+ self.dut, ref, *_ = self.devices
+ assert isinstance(ref, BumblePandoraClient)
+ self.ref = ref
+ # Enable BR/EDR mode and SSP for Bumble devices.
+ self.ref.config.setdefault('classic_enabled', True)
+ self.ref.config.setdefault('classic_ssp_enabled', True)
+ self.ref.config.setdefault(
+ 'server',
+ {
+ 'io_capability': 'no_output_no_input',
+ },
+ )
+
+ def teardown_class(self) -> None:
+ if self.devices:
+ self.devices.stop_all()
+
+ @avatar.asynchronous
+ async def setup_test(self) -> None:
+ await asyncio.gather(self.dut.reset(), self.ref.reset())
+
+ ref_server = Server(self.ref.device)
+ self.ref.rfcomm = RFCOMMService(self.ref.device, ref_server)
+ self.dut.rfcomm = RFCOMM(channel=self.dut.aio.channel)
+
+ @avatar.asynchronous
+ async def test_client_connect_and_exchange_data(self) -> None:
+ # dut is client, ref is server
+ context = grpc.ServicerContext
+ server = await self.ref.rfcomm.StartServer(StartServerRequest(name=TEST_SERVER_NAME, uuid=SERIAL_PORT_UUID),
+ context=context)
+ # Convert StartServerResponse to its server
+ server = server.server
+ rfc_dut_ref, rfc_ref_dut = await asyncio.gather(
+ self.dut.rfcomm.ConnectToServer(address=self.ref.address, uuid=SERIAL_PORT_UUID),
+ self.ref.rfcomm.AcceptConnection(request=AcceptConnectionRequest(server=server), context=context))
+ # Convert Responses to their corresponding RfcommConnection
+ rfc_dut_ref = rfc_dut_ref.connection
+ rfc_ref_dut = rfc_ref_dut.connection
+
+ # Transmit data
+ tx_data = b'Data from dut to ref'
+ await self.dut.rfcomm.Send(data=tx_data, connection=rfc_dut_ref)
+ ref_receive = await self.ref.rfcomm.Receive(request=RxRequest(connection=rfc_ref_dut), context=context)
+ assert_equal(ref_receive.data, tx_data)
+
+ # Receive data
+ rx_data = b'Data from ref to dut'
+ await self.ref.rfcomm.Send(request=TxRequest(connection=rfc_ref_dut, data=rx_data), context=context)
+ dut_receive = await self.dut.rfcomm.Receive(connection=rfc_dut_ref)
+ assert_equal(dut_receive.data.rstrip(b'\x00'), rx_data)
+
+ # Disconnect (from dut)
+ await self.dut.rfcomm.Disconnect(connection=rfc_dut_ref)
+ await self.ref.rfcomm.StopServer(request=StopServerRequest(server=server), context=context)
+
+
+if __name__ == '__main__':
+ logging.basicConfig(level=logging.DEBUG)
+ test_runner.main() # type: ignore
diff --git a/apex/Android.bp b/apex/Android.bp
index c2aabcf0b8..bf75163768 100644
--- a/apex/Android.bp
+++ b/apex/Android.bp
@@ -84,7 +84,6 @@ apex {
],
key: "com.android.bt.key",
certificate: ":com.android.bt.certificate",
- updatable: true,
compressible: false,
visibility: ["//packages/modules/common/build"],
}
diff --git a/flags/a2dp.aconfig b/flags/a2dp.aconfig
index ccf46f8bed..e7b9aa21b0 100644
--- a/flags/a2dp.aconfig
+++ b/flags/a2dp.aconfig
@@ -39,16 +39,6 @@ flag {
}
flag {
- name: "a2dp_broadcast_connection_state_when_turned_off"
- namespace: "bluetooth"
- description: "Broadcast CONNECTION_STATE_CHANGED when A2dpService is turned off while a device is connected"
- bug: "360034472"
- metadata {
- purpose: PURPOSE_BUGFIX
- }
-}
-
-flag {
name: "fix_avdt_rconfig_not_setting_l2cap"
namespace: "bluetooth"
description: "Set L2CAP flushable and high priority after A2DP reconfigure"
@@ -59,26 +49,6 @@ flag {
}
flag {
- name: "a2dp_source_threading_fix"
- namespace: "bluetooth"
- description: "Schedule A2DP source setup operations to bt_main_thread to prevent races"
- bug: "374166531"
- metadata {
- purpose: PURPOSE_BUGFIX
- }
-}
-
-flag {
- name: "a2dp_clear_pending_start_on_session_restart"
- namespace: "bluetooth"
- description: "Clear the kPendingStart flag when the audio session is restarted for codec reconfiguration"
- bug: "378524655"
- metadata {
- purpose: PURPOSE_BUGFIX
- }
-}
-
-flag {
name: "avdt_handle_suspend_cfm_bad_state"
namespace: "bluetooth"
description: "Close connection on AVDTP Suspend Confirmation with BAD STATE error"
diff --git a/flags/gap.aconfig b/flags/gap.aconfig
index d12e294ec7..edc7874fb5 100644
--- a/flags/gap.aconfig
+++ b/flags/gap.aconfig
@@ -30,13 +30,6 @@ flag {
}
flag {
- name: "ble_scan_adv_metrics_redesign"
- namespace: "bluetooth"
- description: "Reimplement BLE scan and advertisement metrics logging."
- bug: "328303508"
-}
-
-flag {
name: "msft_addr_tracking_quirk"
namespace: "bluetooth"
description: "Scanning with MSFT paddress tracking for Realtek BT controllers"
@@ -104,13 +97,6 @@ flag {
}
flag {
- name: "non_wake_alarm_for_rpa_rotation"
- namespace: "bluetooth"
- description: "Use non-wake alarm for LE RPA rotation. go/non-wake-alarm-for-rpa-rotation"
- bug: "360743527"
-}
-
-flag {
name: "gatt_disconnect_fix"
namespace: "bluetooth"
description: "Fix GATT disconnect handling"
@@ -206,16 +192,6 @@ flag {
}
flag {
- name: "drop_acl_fragment_on_disconnect"
- namespace: "bluetooth"
- description: "Drop pending ACL packet fragments for disconnected connection"
- bug: "376379859"
- metadata {
- purpose: PURPOSE_BUGFIX
- }
-}
-
-flag {
name: "configure_scan_on_resume"
namespace: "bluetooth"
description: "Configure scan paramters when start scanning from onResume"
diff --git a/flags/hci.aconfig b/flags/hci.aconfig
index cdd5ca3ab6..6f6b1e70df 100644
--- a/flags/hci.aconfig
+++ b/flags/hci.aconfig
@@ -2,13 +2,6 @@ package: "com.android.bluetooth.flags"
container: "com.android.bt"
flag {
- name: "encryption_change_v2"
- namespace: "bluetooth"
- description: "Enable encryption change V2 event"
- bug: "366018699"
-}
-
-flag {
name: "dont_send_hci_disconnect_repeatedly"
namespace: "bluetooth"
description: "Prevent BT from sending repeated HCI disconnect command"
diff --git a/flags/hid.aconfig b/flags/hid.aconfig
index d40e55821f..ee5728c94f 100644
--- a/flags/hid.aconfig
+++ b/flags/hid.aconfig
@@ -118,3 +118,13 @@ flag {
purpose: PURPOSE_BUGFIX
}
}
+
+flag {
+ name: "hh_state_update_race_fix"
+ namespace: "bluetooth"
+ description: "Fix stuck in connecting state due to race when updating state"
+ bug: "403420458"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
diff --git a/flags/l2cap.aconfig b/flags/l2cap.aconfig
index fec2edd6d5..f82b596674 100644
--- a/flags/l2cap.aconfig
+++ b/flags/l2cap.aconfig
@@ -9,16 +9,6 @@ flag {
}
flag {
- name: "l2cap_le_do_not_adjust_min_interval"
- namespace: "bluetooth"
- description: "Do not adjust min_interval in connection update request"
- bug: "346960036"
- metadata {
- purpose: PURPOSE_BUGFIX
- }
-}
-
-flag {
name: "l2cap_fcs_option_fix"
namespace: "bluetooth"
description: "Use fcs_option for non BASIC mode "
diff --git a/flags/leaudio.aconfig b/flags/leaudio.aconfig
index 9d2c86afa3..a2f77b5658 100644
--- a/flags/leaudio.aconfig
+++ b/flags/leaudio.aconfig
@@ -344,3 +344,13 @@ flag {
purpose: PURPOSE_BUGFIX
}
}
+
+flag {
+ name: "leaudio_use_aggressive_params"
+ namespace: "bluetooth"
+ description: "use aggressive parameters for LE Audio device"
+ bug: "400607635"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
diff --git a/flags/opp.aconfig b/flags/opp.aconfig
index 7e67688ba8..cdba75b756 100644
--- a/flags/opp.aconfig
+++ b/flags/opp.aconfig
@@ -31,3 +31,20 @@ flag {
}
}
+flag {
+ name: "opp_device_picker_extra_intent_apis"
+ is_exported: true
+ namespace: "bluetooth"
+ description: "New API to get the original intent in Bluetooth Device Picker"
+ bug: "395796600"
+}
+
+flag {
+ name: "send_opp_device_picker_extra_intent"
+ namespace: "bluetooth"
+ description: "Send the original intent when opening Bluetooth device picker"
+ bug: "397852103"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
diff --git a/flags/pairing.aconfig b/flags/pairing.aconfig
index bc57bafe9e..f30410db17 100644
--- a/flags/pairing.aconfig
+++ b/flags/pairing.aconfig
@@ -102,16 +102,6 @@ flag {
}
flag {
- name: "smp_state_machine_stuck_after_disconnection_fix"
- namespace: "bluetooth"
- description: "Fix state machine stuck after pairing device disconnection"
- bug: "376306092"
- metadata {
- purpose: PURPOSE_BUGFIX
- }
-}
-
-flag {
name: "prevent_service_connections_on_remove_bond"
namespace: "bluetooth"
description: "Disable service connections on remove bond"
@@ -260,3 +250,23 @@ flag {
purpose: PURPOSE_BUGFIX
}
}
+
+flag {
+ name: "le_peripheral_enc_failure"
+ namespace: "bluetooth"
+ description: "Don't remove bond on LE encryption failure in peripheral role with bonded device, instead just disconnect the link"
+ bug: "403313352"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+flag {
+ name: "immediate_encryption_after_pairing"
+ namespace: "bluetooth"
+ description: "Encrypt BR/EDR link immediately after pairing"
+ bug: "402510244"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
diff --git a/flags/security.aconfig b/flags/security.aconfig
index c83dc02b24..8d5a8c1f31 100644
--- a/flags/security.aconfig
+++ b/flags/security.aconfig
@@ -2,13 +2,6 @@ package: "com.android.bluetooth.flags"
container: "com.android.bt"
flag {
- name: "key_missing_classic_device"
- namespace: "bluetooth"
- description: "Key missing broadcast for Classic devices"
- bug: "333634398"
-}
-
-flag {
name: "key_missing_ble_peripheral"
namespace: "bluetooth"
description: "Key missing broadcast for LE devices in peripheral role"
@@ -66,16 +59,6 @@ flag {
}
flag {
- name: "sec_disconnect_on_le_key_missing"
- namespace: "bluetooth"
- description: "Disconnect LE link when keys are missing during encryption"
- bug: "376680866"
- metadata {
- purpose: PURPOSE_BUGFIX
- }
-}
-
-flag {
name: "guard_bonded_device_properties"
namespace: "bluetooth"
description: "Don't update device properties for bonded devices from the device discovery results"
diff --git a/flags/sockets.aconfig b/flags/sockets.aconfig
index 2eb23b1fcb..6b31e06705 100644
--- a/flags/sockets.aconfig
+++ b/flags/sockets.aconfig
@@ -92,3 +92,13 @@ flag {
purpose: PURPOSE_BUGFIX
}
}
+
+flag {
+ name: "fix_lecoc_socket_available"
+ namespace: "bluetooth"
+ description: "Fix Bluetooth Socket available API for LECOC socket"
+ bug: "402536099"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
diff --git a/flags/system_service.aconfig b/flags/system_service.aconfig
index ea40eb33de..c1cf4f6bd8 100644
--- a/flags/system_service.aconfig
+++ b/flags/system_service.aconfig
@@ -2,6 +2,16 @@ package: "com.android.bluetooth.flags"
container: "com.android.bt"
flag {
+ name: "enable_ble_while_disabling_airplane"
+ namespace: "bluetooth"
+ description: "Fix a race between enabling and handling airplane event"
+ bug: "402563502"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+flag {
name: "kill_instead_of_exit"
namespace: "bluetooth"
description: "There is no value in pretending we are exiting properly. This is a kill and we should express it this way when finishing the process"
diff --git a/framework/Android.bp b/framework/Android.bp
index 36cd93670c..e40f1af6f4 100644
--- a/framework/Android.bp
+++ b/framework/Android.bp
@@ -100,7 +100,6 @@ java_sdk_library {
"ExtraTranslation",
"FlaggedApi",
"GestureBackNavigation",
- "GetterSetterNullability",
"GuardedLogInvocation",
"HandlerLeak",
"InflateParams",
diff --git a/framework/api/system-current.txt b/framework/api/system-current.txt
index 10bdab4b5c..ef922c92e1 100644
--- a/framework/api/system-current.txt
+++ b/framework/api/system-current.txt
@@ -247,7 +247,7 @@ package android.bluetooth {
method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean cancelBondProcess();
method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED, android.Manifest.permission.MODIFY_PHONE_STATE}) public int connect();
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean createBond(int);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean createBondOutOfBand(int, @Nullable android.bluetooth.OobData, @Nullable android.bluetooth.OobData);
+ method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean createBondOutOfBand(int, @Nullable android.bluetooth.OobData, @Nullable android.bluetooth.OobData);
method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int disconnect();
method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}, conditional=true) public boolean fetchUuidsWithSdp(int);
method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int getActiveAudioDevicePolicy();
@@ -369,6 +369,7 @@ package android.bluetooth {
public interface BluetoothDevicePicker {
field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_DEVICE_SELECTED = "android.bluetooth.devicepicker.action.DEVICE_SELECTED";
field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_LAUNCH = "android.bluetooth.devicepicker.action.LAUNCH";
+ field @FlaggedApi("com.android.bluetooth.flags.opp_device_picker_extra_intent_apis") public static final String EXTRA_DEVICE_PICKER_ORIGINAL_SEND_INTENT = "android.bluetooth.extra.DEVICE_PICKER_ORIGINAL_SEND_INTENT";
field public static final String EXTRA_FILTER_TYPE = "android.bluetooth.devicepicker.extra.FILTER_TYPE";
field public static final String EXTRA_LAUNCH_CLASS = "android.bluetooth.devicepicker.extra.DEVICE_PICKER_LAUNCH_CLASS";
field public static final String EXTRA_LAUNCH_PACKAGE = "android.bluetooth.devicepicker.extra.LAUNCH_PACKAGE";
diff --git a/framework/java/android/bluetooth/BluetoothAdapter.java b/framework/java/android/bluetooth/BluetoothAdapter.java
index 40d1153581..1b37497323 100644
--- a/framework/java/android/bluetooth/BluetoothAdapter.java
+++ b/framework/java/android/bluetooth/BluetoothAdapter.java
@@ -3686,6 +3686,9 @@ public final class BluetoothAdapter {
if (mBluetoothLeScanner != null) {
mBluetoothLeScanner.cleanup();
}
+ if (mDistanceMeasurementManager != null) {
+ mDistanceMeasurementManager.cleanup();
+ }
}
} finally {
mServiceLock.writeLock().unlock();
diff --git a/framework/java/android/bluetooth/BluetoothDevice.java b/framework/java/android/bluetooth/BluetoothDevice.java
index c7f3b8a052..d5ec86546c 100644
--- a/framework/java/android/bluetooth/BluetoothDevice.java
+++ b/framework/java/android/bluetooth/BluetoothDevice.java
@@ -1950,7 +1950,21 @@ public final class BluetoothDevice implements Parcelable, Attributable {
@RequiresBluetoothConnectPermission
@RequiresPermission(BLUETOOTH_CONNECT)
public boolean createBond(int transport) {
- return createBondInternal(transport, null, null);
+ if (DBG) log("createBond()");
+ final IBluetooth service = getService();
+ if (service == null || !isBluetoothEnabled()) {
+ Log.w(TAG, "BT not enabled, createBond failed");
+ if (DBG) log(Log.getStackTraceString(new Throwable()));
+ } else if (NULL_MAC_ADDRESS.equals(mAddress)) {
+ Log.e(TAG, "Unable to create bond, invalid address " + mAddress);
+ } else {
+ try {
+ return service.createBond(this, transport, mAttributionSource);
+ } catch (RemoteException e) {
+ Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
+ }
+ }
+ return false;
}
/**
@@ -1974,30 +1988,25 @@ public final class BluetoothDevice implements Parcelable, Attributable {
* @hide
*/
@SystemApi
- @RequiresPermission(BLUETOOTH_CONNECT)
+ @RequiresPermission(allOf = {BLUETOOTH_CONNECT, BLUETOOTH_PRIVILEGED})
public boolean createBondOutOfBand(
int transport, @Nullable OobData remoteP192Data, @Nullable OobData remoteP256Data) {
+ if (DBG) log("createBondOutOfBand()");
+ final IBluetooth service = getService();
+
if (remoteP192Data == null && remoteP256Data == null) {
throw new IllegalArgumentException(
"One or both arguments for the OOB data types are required to not be null. "
+ " Please use createBond() instead if you do not have OOB data to pass.");
}
- return createBondInternal(transport, remoteP192Data, remoteP256Data);
- }
-
- @RequiresPermission(BLUETOOTH_CONNECT)
- private boolean createBondInternal(
- int transport, @Nullable OobData remoteP192Data, @Nullable OobData remoteP256Data) {
- if (DBG) log("createBondInternal()");
- final IBluetooth service = getService();
if (service == null || !isBluetoothEnabled()) {
- Log.w(TAG, "BT not enabled, createBondInternal failed");
+ Log.w(TAG, "BT not enabled, createBondOutOfBand failed");
if (DBG) log(Log.getStackTraceString(new Throwable()));
} else if (NULL_MAC_ADDRESS.equals(mAddress)) {
- Log.e(TAG, "Unable to create bond, invalid address " + mAddress);
+ Log.e(TAG, "Unable to create bond Out of Band, invalid address " + mAddress);
} else {
try {
- return service.createBond(
+ return service.createBondOutOfBand(
this, transport, remoteP192Data, remoteP256Data, mAttributionSource);
} catch (RemoteException e) {
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
diff --git a/framework/java/android/bluetooth/BluetoothDevicePicker.java b/framework/java/android/bluetooth/BluetoothDevicePicker.java
index ee788dae18..7e7cd6d6b7 100644
--- a/framework/java/android/bluetooth/BluetoothDevicePicker.java
+++ b/framework/java/android/bluetooth/BluetoothDevicePicker.java
@@ -18,6 +18,7 @@ package android.bluetooth;
import static android.Manifest.permission.BLUETOOTH_CONNECT;
+import android.annotation.FlaggedApi;
import android.annotation.RequiresPermission;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
@@ -25,6 +26,8 @@ import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
+import com.android.bluetooth.flags.Flags;
+
/**
* A helper to show a system "Device Picker" activity to the user.
*
@@ -64,6 +67,14 @@ public interface BluetoothDevicePicker {
String EXTRA_LAUNCH_CLASS = "android.bluetooth.devicepicker.extra.DEVICE_PICKER_LAUNCH_CLASS";
/**
+ * Extra for the original ACTION_SEND or ACTION_SEND_MULTIPLE intent that triggered the BT
+ * sharing.
+ */
+ @FlaggedApi(Flags.FLAG_OPP_DEVICE_PICKER_EXTRA_INTENT_APIS)
+ String EXTRA_DEVICE_PICKER_ORIGINAL_SEND_INTENT =
+ "android.bluetooth.extra.DEVICE_PICKER_ORIGINAL_SEND_INTENT";
+
+ /**
* Broadcast when one BT device is selected from BT device picker screen. Selected {@link
* BluetoothDevice} is returned in extra data named {@link BluetoothDevice#EXTRA_DEVICE}.
*/
diff --git a/framework/java/android/bluetooth/BluetoothHearingAid.java b/framework/java/android/bluetooth/BluetoothHearingAid.java
index 7e14057546..991efc3dc6 100644
--- a/framework/java/android/bluetooth/BluetoothHearingAid.java
+++ b/framework/java/android/bluetooth/BluetoothHearingAid.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 The Android Open Source Project
+ * Copyright (C) 2018 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.
diff --git a/framework/java/android/bluetooth/BluetoothLeBroadcast.java b/framework/java/android/bluetooth/BluetoothLeBroadcast.java
index 192b95231d..75aec6f996 100644
--- a/framework/java/android/bluetooth/BluetoothLeBroadcast.java
+++ b/framework/java/android/bluetooth/BluetoothLeBroadcast.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2021 The Android Open Source Project
+ * Copyright (C) 2021 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.
diff --git a/framework/java/android/bluetooth/BluetoothLeBroadcastAssistant.java b/framework/java/android/bluetooth/BluetoothLeBroadcastAssistant.java
index d72fc1a50f..3c6cbed382 100644
--- a/framework/java/android/bluetooth/BluetoothLeBroadcastAssistant.java
+++ b/framework/java/android/bluetooth/BluetoothLeBroadcastAssistant.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2021 The Android Open Source Project
+ * Copyright (C) 2021 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.
diff --git a/framework/java/android/bluetooth/BluetoothLeBroadcastChannel.java b/framework/java/android/bluetooth/BluetoothLeBroadcastChannel.java
index 5149b19211..873edac288 100644
--- a/framework/java/android/bluetooth/BluetoothLeBroadcastChannel.java
+++ b/framework/java/android/bluetooth/BluetoothLeBroadcastChannel.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/framework/java/android/bluetooth/BluetoothLeBroadcastMetadata.java b/framework/java/android/bluetooth/BluetoothLeBroadcastMetadata.java
index 562e0b7835..f40f4d7397 100644
--- a/framework/java/android/bluetooth/BluetoothLeBroadcastMetadata.java
+++ b/framework/java/android/bluetooth/BluetoothLeBroadcastMetadata.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/framework/java/android/bluetooth/BluetoothLeBroadcastReceiveState.java b/framework/java/android/bluetooth/BluetoothLeBroadcastReceiveState.java
index 3fa4dcc7a3..a0ae67799c 100644
--- a/framework/java/android/bluetooth/BluetoothLeBroadcastReceiveState.java
+++ b/framework/java/android/bluetooth/BluetoothLeBroadcastReceiveState.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/framework/java/android/bluetooth/BluetoothLeBroadcastSettings.java b/framework/java/android/bluetooth/BluetoothLeBroadcastSettings.java
index 48d53c4cb3..182780e6b9 100644
--- a/framework/java/android/bluetooth/BluetoothLeBroadcastSettings.java
+++ b/framework/java/android/bluetooth/BluetoothLeBroadcastSettings.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 The Android Open Source Project
+ * Copyright (C) 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.
diff --git a/framework/java/android/bluetooth/BluetoothLeBroadcastSubgroup.java b/framework/java/android/bluetooth/BluetoothLeBroadcastSubgroup.java
index 5d150ed78c..cc87421e50 100644
--- a/framework/java/android/bluetooth/BluetoothLeBroadcastSubgroup.java
+++ b/framework/java/android/bluetooth/BluetoothLeBroadcastSubgroup.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/framework/java/android/bluetooth/BluetoothLeBroadcastSubgroupSettings.java b/framework/java/android/bluetooth/BluetoothLeBroadcastSubgroupSettings.java
index d903435974..b355f43473 100644
--- a/framework/java/android/bluetooth/BluetoothLeBroadcastSubgroupSettings.java
+++ b/framework/java/android/bluetooth/BluetoothLeBroadcastSubgroupSettings.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 The Android Open Source Project
+ * Copyright (C) 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.
diff --git a/framework/java/android/bluetooth/BluetoothSinkAudioPolicy.java b/framework/java/android/bluetooth/BluetoothSinkAudioPolicy.java
index 5a11a7fbe5..5ebffbd430 100644
--- a/framework/java/android/bluetooth/BluetoothSinkAudioPolicy.java
+++ b/framework/java/android/bluetooth/BluetoothSinkAudioPolicy.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/framework/java/android/bluetooth/BluetoothSocketSettings.java b/framework/java/android/bluetooth/BluetoothSocketSettings.java
index 3f222d4717..04151ef3e6 100644
--- a/framework/java/android/bluetooth/BluetoothSocketSettings.java
+++ b/framework/java/android/bluetooth/BluetoothSocketSettings.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 The Android Open Source Project
+ * Copyright (C) 2024 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.
diff --git a/framework/java/android/bluetooth/le/ChannelSoundingParams.java b/framework/java/android/bluetooth/le/ChannelSoundingParams.java
index cbaa01d0fb..aa0202a3be 100644
--- a/framework/java/android/bluetooth/le/ChannelSoundingParams.java
+++ b/framework/java/android/bluetooth/le/ChannelSoundingParams.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 The Android Open Source Project
+ * Copyright (C) 2024 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.
diff --git a/framework/java/android/bluetooth/le/DistanceMeasurementManager.java b/framework/java/android/bluetooth/le/DistanceMeasurementManager.java
index 6209e31946..94715301f0 100644
--- a/framework/java/android/bluetooth/le/DistanceMeasurementManager.java
+++ b/framework/java/android/bluetooth/le/DistanceMeasurementManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -24,6 +24,7 @@ import static java.util.Objects.requireNonNull;
import android.annotation.FlaggedApi;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.RequiresNoPermission;
import android.annotation.RequiresPermission;
import android.annotation.SuppressLint;
import android.annotation.SystemApi;
@@ -271,6 +272,16 @@ public final class DistanceMeasurementManager {
return Collections.emptySet();
}
+ /**
+ * Clear session map. Should be called when bluetooth is down.
+ *
+ * @hide
+ */
+ @RequiresNoPermission
+ public void cleanup() {
+ mSessionMap.clear();
+ }
+
@SuppressLint("AndroidFrameworkBluetoothPermission")
private final IDistanceMeasurementCallback mCallbackWrapper =
new IDistanceMeasurementCallback.Stub() {
diff --git a/framework/java/android/bluetooth/le/DistanceMeasurementMethod.java b/framework/java/android/bluetooth/le/DistanceMeasurementMethod.java
index 0d9f187889..a677f0e810 100644
--- a/framework/java/android/bluetooth/le/DistanceMeasurementMethod.java
+++ b/framework/java/android/bluetooth/le/DistanceMeasurementMethod.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/framework/java/android/bluetooth/le/DistanceMeasurementParams.java b/framework/java/android/bluetooth/le/DistanceMeasurementParams.java
index 51a4a595a9..eadcd3078c 100644
--- a/framework/java/android/bluetooth/le/DistanceMeasurementParams.java
+++ b/framework/java/android/bluetooth/le/DistanceMeasurementParams.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/framework/java/android/bluetooth/le/DistanceMeasurementResult.java b/framework/java/android/bluetooth/le/DistanceMeasurementResult.java
index 2292371e56..c757daa710 100644
--- a/framework/java/android/bluetooth/le/DistanceMeasurementResult.java
+++ b/framework/java/android/bluetooth/le/DistanceMeasurementResult.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/framework/java/android/bluetooth/le/DistanceMeasurementSession.java b/framework/java/android/bluetooth/le/DistanceMeasurementSession.java
index 3241e68b59..e2dd181810 100644
--- a/framework/java/android/bluetooth/le/DistanceMeasurementSession.java
+++ b/framework/java/android/bluetooth/le/DistanceMeasurementSession.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/framework/java/android/bluetooth/le/TransportBlockFilter.java b/framework/java/android/bluetooth/le/TransportBlockFilter.java
index 5da9bf658f..1a8418c691 100644
--- a/framework/java/android/bluetooth/le/TransportBlockFilter.java
+++ b/framework/java/android/bluetooth/le/TransportBlockFilter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 The Android Open Source Project
+ * Copyright (C) 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.
diff --git a/framework/tests/bumble/src/android/bluetooth/pairing/OobPairingTest.java b/framework/tests/bumble/src/android/bluetooth/pairing/OobPairingTest.java
index bdfa42dd65..0b0da56f7b 100644
--- a/framework/tests/bumble/src/android/bluetooth/pairing/OobPairingTest.java
+++ b/framework/tests/bumble/src/android/bluetooth/pairing/OobPairingTest.java
@@ -19,6 +19,8 @@ package android.bluetooth.pairing;
import static androidx.test.espresso.intent.matcher.IntentMatchers.hasAction;
import static androidx.test.espresso.intent.matcher.IntentMatchers.hasExtra;
+import static com.google.common.truth.Truth.assertThat;
+
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothAdapter.OobDataCallback;
import android.bluetooth.BluetoothDevice;
@@ -340,11 +342,14 @@ public class OobPairingTest {
while (true) {
if (scanningResponseIterator.hasNext()) {
ScanningResponse scanningResponse = scanningResponseIterator.next();
- // select first available device
+ // select first available device with Random address type
deviceAddr = scanningResponse.getRandom();
- break;
+ if (deviceAddr != null) {
+ break;
+ }
}
}
+ assertThat(deviceAddr).isNotNull();
ConnectLEResponse leConn =
mBumble.hostBlocking()
diff --git a/framework/tests/unit/src/android/bluetooth/BluetoothActivityEnergyInfoTest.java b/framework/tests/unit/src/android/bluetooth/BluetoothActivityEnergyInfoTest.java
index eb8e074953..fdb8bd9f25 100644
--- a/framework/tests/unit/src/android/bluetooth/BluetoothActivityEnergyInfoTest.java
+++ b/framework/tests/unit/src/android/bluetooth/BluetoothActivityEnergyInfoTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/framework/tests/unit/src/android/bluetooth/BluetoothAudioConfigTest.java b/framework/tests/unit/src/android/bluetooth/BluetoothAudioConfigTest.java
index 2360dcad14..49f0f745b6 100644
--- a/framework/tests/unit/src/android/bluetooth/BluetoothAudioConfigTest.java
+++ b/framework/tests/unit/src/android/bluetooth/BluetoothAudioConfigTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/framework/tests/unit/src/android/bluetooth/BluetoothCodecConfigTest.java b/framework/tests/unit/src/android/bluetooth/BluetoothCodecConfigTest.java
index 316ef1f109..d2ca867f01 100644
--- a/framework/tests/unit/src/android/bluetooth/BluetoothCodecConfigTest.java
+++ b/framework/tests/unit/src/android/bluetooth/BluetoothCodecConfigTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 The Android Open Source Project
+ * Copyright (C) 2018 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.
diff --git a/framework/tests/unit/src/android/bluetooth/BluetoothCodecStatusTest.java b/framework/tests/unit/src/android/bluetooth/BluetoothCodecStatusTest.java
index 85422f568a..25b1812bf5 100644
--- a/framework/tests/unit/src/android/bluetooth/BluetoothCodecStatusTest.java
+++ b/framework/tests/unit/src/android/bluetooth/BluetoothCodecStatusTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 The Android Open Source Project
+ * Copyright (C) 2018 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.
diff --git a/framework/tests/unit/src/android/bluetooth/BluetoothDeviceTest.java b/framework/tests/unit/src/android/bluetooth/BluetoothDeviceTest.java
index 55263c4400..d173645914 100644
--- a/framework/tests/unit/src/android/bluetooth/BluetoothDeviceTest.java
+++ b/framework/tests/unit/src/android/bluetooth/BluetoothDeviceTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 The Android Open Source Project
+ * Copyright (C) 2024 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.
diff --git a/framework/tests/unit/src/android/bluetooth/CallbackWrapperTest.java b/framework/tests/unit/src/android/bluetooth/CallbackWrapperTest.java
index 0721ead366..15dad9ca3b 100644
--- a/framework/tests/unit/src/android/bluetooth/CallbackWrapperTest.java
+++ b/framework/tests/unit/src/android/bluetooth/CallbackWrapperTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 The Android Open Source Project
+ * Copyright (C) 2024 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.
diff --git a/framework/tests/unit/src/android/bluetooth/SdpDipRecordTest.java b/framework/tests/unit/src/android/bluetooth/SdpDipRecordTest.java
index b8a0d48f66..380ef9d34f 100644
--- a/framework/tests/unit/src/android/bluetooth/SdpDipRecordTest.java
+++ b/framework/tests/unit/src/android/bluetooth/SdpDipRecordTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/framework/tests/unit/src/android/bluetooth/SdpMnsRecordTest.java b/framework/tests/unit/src/android/bluetooth/SdpMnsRecordTest.java
index 5e686d1bfc..d314a959c3 100644
--- a/framework/tests/unit/src/android/bluetooth/SdpMnsRecordTest.java
+++ b/framework/tests/unit/src/android/bluetooth/SdpMnsRecordTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/framework/tests/unit/src/android/bluetooth/SdpOppOpsRecordTest.java b/framework/tests/unit/src/android/bluetooth/SdpOppOpsRecordTest.java
index dcff94073d..8ab38cbb19 100644
--- a/framework/tests/unit/src/android/bluetooth/SdpOppOpsRecordTest.java
+++ b/framework/tests/unit/src/android/bluetooth/SdpOppOpsRecordTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/framework/tests/unit/src/android/bluetooth/SdpPseRecordTest.java b/framework/tests/unit/src/android/bluetooth/SdpPseRecordTest.java
index c9eeaa2940..1f1ce64540 100644
--- a/framework/tests/unit/src/android/bluetooth/SdpPseRecordTest.java
+++ b/framework/tests/unit/src/android/bluetooth/SdpPseRecordTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/framework/tests/unit/src/android/bluetooth/SdpRecordTest.java b/framework/tests/unit/src/android/bluetooth/SdpRecordTest.java
index f7afe42688..74fc82bef4 100644
--- a/framework/tests/unit/src/android/bluetooth/SdpRecordTest.java
+++ b/framework/tests/unit/src/android/bluetooth/SdpRecordTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/framework/tests/unit/src/android/bluetooth/SdpSapsRecordTest.java b/framework/tests/unit/src/android/bluetooth/SdpSapsRecordTest.java
index eedfb9ac64..5316bc915f 100644
--- a/framework/tests/unit/src/android/bluetooth/SdpSapsRecordTest.java
+++ b/framework/tests/unit/src/android/bluetooth/SdpSapsRecordTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/offload/leaudio/hci/proxy.rs b/offload/leaudio/hci/proxy.rs
index 933389d315..adc2dbd34d 100644
--- a/offload/leaudio/hci/proxy.rs
+++ b/offload/leaudio/hci/proxy.rs
@@ -195,10 +195,16 @@ impl Module for LeAudioModule {
);
}
- Ok(Command::LeSetupIsoDataPath(ref c)) if c.data_path_id == DATA_PATH_ID_SOFTWARE => {
+ Ok(Command::LeSetupIsoDataPath(ref c)) if c.data_path_id == DATA_PATH_ID_SOFTWARE => 'command: {
assert_eq!(c.data_path_direction, hci::LeDataPathDirection::Input);
let mut state = self.state.lock().unwrap();
- let stream = state.stream.get_mut(&c.connection_handle).unwrap();
+ let Some(stream) = state.stream.get_mut(&c.connection_handle) else {
+ log::warn!(
+ "Setup ISO Data Path on non existing BIS/CIS handle: 0x{:03x}",
+ c.connection_handle
+ );
+ break 'command;
+ };
stream.state = StreamState::Enabling;
// Phase 1 limitation: The controller does not implement HCI Link Feedback event,
@@ -209,6 +215,16 @@ impl Module for LeAudioModule {
return;
}
+ Ok(Command::LeRemoveIsoDataPath(ref c)) => {
+ let mut state = self.state.lock().unwrap();
+ if state.stream.get_mut(&c.connection_handle).is_none() {
+ log::warn!(
+ "Remove ISO Data Path on non existing BIS/CIS handle: 0x{:03x}",
+ c.connection_handle
+ );
+ }
+ }
+
_ => (),
}
@@ -250,7 +266,9 @@ impl Module for LeAudioModule {
ReturnParameters::LeSetupIsoDataPath(ref ret) => 'event: {
let mut state = self.state.lock().unwrap();
- let stream = state.stream.get_mut(&ret.connection_handle).unwrap();
+ let Some(stream) = state.stream.get_mut(&ret.connection_handle) else {
+ break 'event;
+ };
stream.state =
if stream.state == StreamState::Enabling && ret.status == Status::Success {
StreamState::Enabled
@@ -278,9 +296,11 @@ impl Module for LeAudioModule {
);
}
- ReturnParameters::LeRemoveIsoDataPath(ref ret) if ret.status == Status::Success => {
+ ReturnParameters::LeRemoveIsoDataPath(ref ret) if ret.status == Status::Success => 'event: {
let mut state = self.state.lock().unwrap();
- let stream = state.stream.get_mut(&ret.connection_handle).unwrap();
+ let Some(stream) = state.stream.get_mut(&ret.connection_handle) else {
+ break 'event;
+ };
if stream.state == StreamState::Enabled {
Service::stop_stream(ret.connection_handle);
}
diff --git a/service/Android.bp b/service/Android.bp
index 1532b89d3c..4b608dd4b3 100644
--- a/service/Android.bp
+++ b/service/Android.bp
@@ -72,7 +72,6 @@ java_library {
static_libs: [
"androidx.annotation_annotation",
"androidx.appcompat_appcompat",
- "bluetooth-manager-service-proto-java-gen",
"bluetooth-nano-protos",
"bluetooth-proto-enums-java-gen",
"bluetooth_flags_java_lib",
@@ -121,21 +120,6 @@ java_library {
}
java_library {
- name: "bluetooth-manager-service-proto-java-gen",
- srcs: [":srcs_bluetooth_manager_service_proto"],
- installable: false,
-
- proto: {
- type: "stream",
- include_dirs: ["external/protobuf/src"],
- },
-
- sdk_version: "system_server_current",
- min_sdk_version: "Tiramisu",
- apex_available: ["com.android.bt"],
-}
-
-java_library {
name: "bluetooth-nano-protos",
srcs: [":system-messages-proto-src"],
installable: false,
@@ -183,7 +167,6 @@ android_robolectric_test {
static_libs: [
"androidx.test.core",
"androidx.test.ext.truth",
- "bluetooth-manager-service-proto-java-gen",
"bluetooth-nano-protos",
"bluetooth-proto-enums-java-gen",
"bluetooth_flags_java_lib",
diff --git a/service/kls-classpath b/service/kls-classpath
index 94c74875ad..3ea610246d 100755
--- a/service/kls-classpath
+++ b/service/kls-classpath
@@ -16,7 +16,6 @@ CLASSPATH+=":$ROOT/out/soong/.intermediates/packages/modules/Bluetooth/service/c
CLASSPATH+=":$ROOT/out/soong/.intermediates/packages/modules/Bluetooth/framework/framework-bluetooth.impl/android_common/turbine-jarjar/framework-bluetooth.impl.jar"
CLASSPATH+=":$ROOT/out/soong/.intermediates/prebuilts/sdk/current/androidx/m2repository/androidx/annotation/annotation-jvm/1.8.0-alpha01/androidx.annotation_annotation/android_common_apex33/turbine-combined/androidx.annotation_annotation.jar"
-CLASSPATH+=":$ROOT/out/soong/.intermediates/packages/modules/Bluetooth/service/bluetooth-manager-service-proto-java-gen/android_common_apex33/turbine-combined/bluetooth-manager-service-proto-java-gen.jar"
CLASSPATH+=":$ROOT/out/soong/.intermediates/packages/modules/Bluetooth/service/bluetooth-nano-protos/android_common_apex33/turbine-combined/bluetooth-nano-protos.jar"
CLASSPATH+=":$ROOT/out/soong/.intermediates/packages/modules/Bluetooth/android/app/bluetooth-proto-enums-java-gen/android_common_apex33/turbine-combined/bluetooth-proto-enums-java-gen.jar"
CLASSPATH+=":$ROOT/out/soong/.intermediates/packages/modules/Bluetooth/flags/bluetooth_flags_java_lib/android_common_apex33/turbine-combined/bluetooth_flags_java_lib.jar"
diff --git a/service/src/ActiveLog.kt b/service/src/ActiveLog.kt
index 46e3a5570d..ac49031f90 100644
--- a/service/src/ActiveLog.kt
+++ b/service/src/ActiveLog.kt
@@ -30,14 +30,12 @@ import android.bluetooth.BluetoothProtoEnums.ENABLE_DISABLE_REASON_START_ERROR
import android.bluetooth.BluetoothProtoEnums.ENABLE_DISABLE_REASON_SYSTEM_BOOT
import android.bluetooth.BluetoothProtoEnums.ENABLE_DISABLE_REASON_USER_SWITCH
import android.os.Binder
-import android.util.proto.ProtoOutputStream
import androidx.annotation.VisibleForTesting
import com.android.bluetooth.BluetoothStatsLog
import com.android.bluetooth.BluetoothStatsLog.BLUETOOTH_ENABLED_STATE_CHANGED
import com.android.bluetooth.BluetoothStatsLog.BLUETOOTH_ENABLED_STATE_CHANGED__STATE__DISABLED
import com.android.bluetooth.BluetoothStatsLog.BLUETOOTH_ENABLED_STATE_CHANGED__STATE__ENABLED
import com.android.bluetooth.BluetoothStatsLog.BLUETOOTH_ENABLED_STATE_CHANGED__STATE__UNKNOWN
-import com.android.server.BluetoothManagerServiceDumpProto as BtProto
import java.io.PrintWriter
private const val TAG = "ActiveLogs"
@@ -58,13 +56,6 @@ object ActiveLogs {
}
@JvmStatic
- fun dumpProto(proto: ProtoOutputStream) {
- val token = proto.start(BtProto.ACTIVE_LOGS)
- activeLogs.forEach { it.dump(proto) }
- proto.end(token)
- }
-
- @JvmStatic
fun add(reason: Int, enable: Boolean) {
add(reason, enable, "BluetoothSystemServer", false)
}
@@ -124,13 +115,6 @@ internal class ActiveLog(
(if (isBle) "Ble" else "") +
"]. \tReason is " +
getEnableDisableReasonString(reason)
-
- fun dump(proto: ProtoOutputStream) {
- proto.write(BtProto.ActiveLog.TIMESTAMP_MS, timestamp)
- proto.write(BtProto.ActiveLog.ENABLE, enable)
- proto.write(BtProto.ActiveLog.PACKAGE_NAME, packageName)
- proto.write(BtProto.ActiveLog.REASON, reason)
- }
}
private fun getEnableDisableReasonString(reason: Int): String {
diff --git a/service/src/ActiveLogTest.kt b/service/src/ActiveLogTest.kt
index ccd86a375e..baa5076626 100644
--- a/service/src/ActiveLogTest.kt
+++ b/service/src/ActiveLogTest.kt
@@ -26,7 +26,6 @@ import android.bluetooth.BluetoothProtoEnums.ENABLE_DISABLE_REASON_SATELLITE_MOD
import android.bluetooth.BluetoothProtoEnums.ENABLE_DISABLE_REASON_START_ERROR
import android.bluetooth.BluetoothProtoEnums.ENABLE_DISABLE_REASON_SYSTEM_BOOT
import android.bluetooth.BluetoothProtoEnums.ENABLE_DISABLE_REASON_USER_SWITCH
-import android.util.proto.ProtoOutputStream
import com.android.server.bluetooth.ActiveLogs
import com.android.server.bluetooth.Log
import com.google.common.truth.Truth.assertThat
@@ -137,14 +136,4 @@ class ActiveLogTest {
".*UNKNOWN\\[\\d+\\]\n"
)
}
-
- @Test
- fun protoDump() {
- ActiveLogs.add(ENABLE_DISABLE_REASON_APPLICATION_REQUEST, false)
-
- val proto = ProtoOutputStream()
- ActiveLogs.dumpProto(proto)
-
- assertThat(proto.getRawSize()).isEqualTo(48)
- }
}
diff --git a/service/src/com/android/server/bluetooth/BluetoothManagerService.java b/service/src/com/android/server/bluetooth/BluetoothManagerService.java
index 216b621794..b797d6ceac 100644
--- a/service/src/com/android/server/bluetooth/BluetoothManagerService.java
+++ b/service/src/com/android/server/bluetooth/BluetoothManagerService.java
@@ -78,7 +78,6 @@ import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
import android.sysprop.BluetoothProperties;
-import android.util.proto.ProtoOutputStream;
import androidx.annotation.RequiresApi;
@@ -86,7 +85,6 @@ import com.android.bluetooth.flags.Flags;
import com.android.internal.annotations.VisibleForTesting;
import com.android.modules.expresslog.Counter;
import com.android.modules.expresslog.Histogram;
-import com.android.server.BluetoothManagerServiceDumpProto;
import com.android.server.bluetooth.airplane.AirplaneModeListener;
import com.android.server.bluetooth.satellite.SatelliteModeListener;
@@ -96,7 +94,6 @@ import kotlin.Unit;
import kotlin.time.TimeSource;
import java.io.FileDescriptor;
-import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
@@ -141,10 +138,17 @@ class BluetoothManagerService {
// Delay for retrying enable and disable in msec
@VisibleForTesting static final int ENABLE_DISABLE_DELAY_MS = 300 * HW_MULTIPLIER;
+ // TODO: b/402209603 remove along with system_server_remove_extra_thread_jump
@VisibleForTesting static final int MESSAGE_ENABLE = 1;
+ // TODO: b/402209603 remove along with system_server_remove_extra_thread_jump
@VisibleForTesting static final int MESSAGE_DISABLE = 2;
+
+ // TODO: b/402209603 remove along with system_server_remove_extra_thread_jump
@VisibleForTesting static final int MESSAGE_HANDLE_ENABLE_DELAYED = 3;
+
+ // TODO: b/402209603 remove along with system_server_remove_extra_thread_jump
@VisibleForTesting static final int MESSAGE_HANDLE_DISABLE_DELAYED = 4;
+
@VisibleForTesting static final int MESSAGE_BLUETOOTH_SERVICE_CONNECTED = 40;
@VisibleForTesting static final int MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED = 41;
@VisibleForTesting static final int MESSAGE_RESTART_BLUETOOTH_SERVICE = 42;
@@ -328,8 +332,9 @@ class BluetoothManagerService {
} else if (state != STATE_ON && state != STATE_OFF && state != STATE_BLE_ON) {
// Bluetooth is turning state
return ADD_PROXY_DELAY_MS;
- } else if (mHandler.hasMessages(MESSAGE_ENABLE)
- || mHandler.hasMessages(MESSAGE_DISABLE)
+ } else if ((!Flags.systemServerRemoveExtraThreadJump()
+ && (mHandler.hasMessages(MESSAGE_ENABLE)
+ || mHandler.hasMessages(MESSAGE_DISABLE)))
|| mHandler.hasMessages(MESSAGE_HANDLE_ENABLE_DELAYED)
|| mHandler.hasMessages(MESSAGE_HANDLE_DISABLE_DELAYED)
|| mHandler.hasMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE)
@@ -1039,6 +1044,42 @@ class BluetoothManagerService {
return true;
}
+ private static CompletableFuture<Void> createDeathNotifier(IBinder binder) {
+ CompletableFuture<Void> deathNotifier = new CompletableFuture<>();
+ try {
+ binder.linkToDeath(
+ () -> {
+ Log.i(TAG, "Successfully received Bluetooth death");
+ deathNotifier.complete(null);
+ },
+ 0);
+ } catch (RemoteException e) {
+ Log.e(TAG, "listenBinderDeath(): Failed to linkToDeath", e);
+ deathNotifier.complete(null);
+ }
+ return deathNotifier;
+ }
+
+ private static void killBluetoothProcess(
+ AdapterBinder adapter, CompletableFuture<Void> deathNotifier) {
+ try {
+ // Force kill Bluetooth to make sure its process is not reused.
+ // Note: In a perfect world, we should be able to re-init the same process.
+ // Unfortunately, this requires an heavy rework of the Bluetooth app
+ // TODO: b/339501753 - Properly stop Bluetooth without killing it
+ adapter.killBluetoothProcess();
+
+ deathNotifier.get(2_000, TimeUnit.MILLISECONDS);
+ } catch (android.os.DeadObjectException e) {
+ // Reduce exception to info and skip waiting (Bluetooth is dead as wanted)
+ Log.i(TAG, "killBluetoothProcess(): Bluetooth already dead 💀");
+ } catch (RemoteException e) {
+ Log.e(TAG, "killBluetoothProcess(): Unable to call killBluetoothProcess", e);
+ } catch (TimeoutException | InterruptedException | ExecutionException e) {
+ Log.e(TAG, "killBluetoothProcess(): Bluetooth death not received after > 2000ms", e);
+ }
+ }
+
void unbindAndFinish() {
Log.d(TAG, "unbindAndFinish(): mAdapter=" + mAdapter + " isBinding=" + isBinding());
@@ -1055,40 +1096,13 @@ class BluetoothManagerService {
Log.e(TAG, "unbindAndFinish(): Unable to unregister BluetoothCallback", e);
}
- CompletableFuture<Void> binderDead = new CompletableFuture<>();
- try {
- mAdapter.getAdapterBinder()
- .asBinder()
- .linkToDeath(
- () -> {
- Log.i(TAG, "Successfully received Bluetooth death");
- binderDead.complete(null);
- },
- 0);
- } catch (RemoteException e) {
- Log.e(TAG, "unbindAndFinish(): Failed to linkToDeath", e);
- binderDead.complete(null);
- }
+ CompletableFuture<Void> deathNotifier =
+ createDeathNotifier(mAdapter.getAdapterBinder().asBinder());
// Unbind first to avoid receiving unwanted "onServiceDisconnected"
mContext.unbindService(mConnection);
- try {
- // Force kill Bluetooth to make sure its process is not reused.
- // Note: In a perfect world, we should be able to re-init the same process.
- // Unfortunately, this requires an heavy rework of the Bluetooth app
- // TODO: b/339501753 - Properly stop Bluetooth without killing it
- mAdapter.killBluetoothProcess();
-
- binderDead.get(2_000, TimeUnit.MILLISECONDS);
- } catch (android.os.DeadObjectException e) {
- // Reduce exception to info and skip waiting (Bluetooth is dead as wanted)
- Log.i(TAG, "unbindAndFinish(): Bluetooth already dead 💀");
- } catch (RemoteException e) {
- Log.e(TAG, "unbindAndFinish(): Unable to call killBluetoothProcess", e);
- } catch (TimeoutException | InterruptedException | ExecutionException e) {
- Log.e(TAG, "unbindAndFinish(): Bluetooth death not received after > 2000ms", e);
- }
+ killBluetoothProcess(mAdapter, deathNotifier);
long timeSpentForShutdown = System.currentTimeMillis() - currentTimeMs;
mShutdownLatencyHistogram.logSample((float) timeSpentForShutdown);
@@ -1229,10 +1243,10 @@ class BluetoothManagerService {
}
if (Flags.setComponentAvailableFix()) {
- mHandler
- .obtainMessage(MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED,
- componentName.getPackageName())
- .sendToTarget();
+ mHandler.obtainMessage(
+ MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED,
+ componentName.getPackageName())
+ .sendToTarget();
} else {
mHandler.sendEmptyMessage(MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED);
}
@@ -1253,8 +1267,12 @@ class BluetoothManagerService {
public void handleMessage(Message msg) {
switch (msg.what) {
case MESSAGE_ENABLE:
- int quietEnable = msg.arg1;
- int isBle = msg.arg2;
+ if (Flags.systemServerRemoveExtraThreadJump()) {
+ break;
+ }
+
+ boolean quietEnable = msg.arg1 != 0;
+ boolean isBle = msg.arg2 != 0;
Log.d(
TAG,
@@ -1266,74 +1284,30 @@ class BluetoothManagerService {
break;
case MESSAGE_DISABLE:
+ if (Flags.systemServerRemoveExtraThreadJump()) {
+ break;
+ }
+
Log.d(TAG, "MESSAGE_DISABLE: mAdapter=" + mAdapter);
handleDisableMessage();
break;
case MESSAGE_HANDLE_ENABLE_DELAYED:
- // The Bluetooth is turning off, wait for STATE_OFF
- if (!mState.oneOf(STATE_OFF)) {
- if (mWaitForEnableRetry < MAX_WAIT_FOR_ENABLE_DISABLE_RETRIES) {
- mWaitForEnableRetry++;
- mHandler.sendEmptyMessageDelayed(
- MESSAGE_HANDLE_ENABLE_DELAYED, ENABLE_DISABLE_DELAY_MS);
- break;
- } else {
- Log.e(TAG, "Wait for STATE_OFF timeout");
- }
- }
- // Either state is changed to STATE_OFF or reaches the maximum retry, we
- // should move forward to the next step.
- mWaitForEnableRetry = 0;
- mHandler.sendEmptyMessageDelayed(
- MESSAGE_RESTART_BLUETOOTH_SERVICE, getServiceRestartMs());
- Log.d(TAG, "Handle enable is finished");
+ Log.d(TAG, "MESSAGE_HANDLE_ENABLE_DELAYED: mAdapter=" + mAdapter);
+
+ handleEnableDelayed();
break;
case MESSAGE_HANDLE_DISABLE_DELAYED:
boolean disabling = (msg.arg1 == 1);
- Log.d(TAG, "MESSAGE_HANDLE_DISABLE_DELAYED: disabling:" + disabling);
- if (!disabling) {
- // The Bluetooth is turning on, wait for STATE_ON
- if (!mState.oneOf(STATE_ON)) {
- if (mWaitForDisableRetry < MAX_WAIT_FOR_ENABLE_DISABLE_RETRIES) {
- mWaitForDisableRetry++;
- mHandler.sendEmptyMessageDelayed(
- MESSAGE_HANDLE_DISABLE_DELAYED, ENABLE_DISABLE_DELAY_MS);
- break;
- } else {
- Log.e(TAG, "Wait for STATE_ON timeout");
- }
- }
- // Either state is changed to STATE_ON or reaches the maximum retry, we
- // should move forward to the next step.
- mWaitForDisableRetry = 0;
- mEnable = false;
- onToBleOn();
- // Wait for state exiting STATE_ON
- Message disableDelayedMsg =
- mHandler.obtainMessage(MESSAGE_HANDLE_DISABLE_DELAYED, 1, 0);
- mHandler.sendMessageDelayed(disableDelayedMsg, ENABLE_DISABLE_DELAY_MS);
- } else {
- // The Bluetooth is turning off, wait for exiting STATE_ON
- if (mState.oneOf(STATE_ON)) {
- if (mWaitForDisableRetry < MAX_WAIT_FOR_ENABLE_DISABLE_RETRIES) {
- mWaitForDisableRetry++;
- Message disableDelayedMsg =
- mHandler.obtainMessage(
- MESSAGE_HANDLE_DISABLE_DELAYED, 1, 0);
- mHandler.sendMessageDelayed(
- disableDelayedMsg, ENABLE_DISABLE_DELAY_MS);
- break;
- } else {
- Log.e(TAG, "Wait for exiting STATE_ON timeout");
- }
- }
- // Either state is exited from STATE_ON or reaches the maximum retry, we
- // should move forward to the next step.
- Log.d(TAG, "Handle disable is finished");
- }
+
+ Log.d(
+ TAG,
+ ("MESSAGE_HANDLE_DISABLE_DELAYED(disabling=" + disabling + ")")
+ + (": mAdapter=" + mAdapter));
+
+ handleDisableDelayed(disabling);
break;
case MESSAGE_RESTORE_USER_SETTING_OFF:
@@ -1360,6 +1334,15 @@ class BluetoothManagerService {
case MESSAGE_BLUETOOTH_SERVICE_CONNECTED:
IBinder service = (IBinder) msg.obj;
+
+ // Handle case where disable was called before binding complete.
+ if (Flags.systemServerRemoveExtraThreadJump() && !isBinding() && !mEnable) {
+ Log.d(TAG, "MESSAGE_BLUETOOTH_SERVICE_CONNECTED: after cancelling binding");
+ AdapterBinder adapter =
+ BluetoothServerProxy.getInstance().createAdapterBinder(service);
+ killBluetoothProcess(adapter, createDeathNotifier(service));
+ break;
+ }
Log.d(TAG, "MESSAGE_BLUETOOTH_SERVICE_CONNECTED: service=" + service);
// Remove timeout
@@ -1379,7 +1362,7 @@ class BluetoothManagerService {
offToBleOn();
sendBluetoothServiceUpCallback();
- if (!mEnable) {
+ if (!Flags.systemServerRemoveExtraThreadJump() && !mEnable) {
waitForState(STATE_ON);
onToBleOn();
}
@@ -1408,13 +1391,31 @@ class BluetoothManagerService {
}
// If we tried to enable BT while BT was in the process of shutting down,
// wait for the BT process to fully tear down and then force a restart
- // here. This is a bit of a hack (b/29363429).
+ // here. This is a bit of a hack (b/29363429).
if (prevState == STATE_BLE_TURNING_OFF && newState == STATE_OFF) {
- if (mEnable) {
- Log.d(TAG, "Entering STATE_OFF but mEnabled is true; restarting.");
- waitForState(STATE_OFF);
- mHandler.sendEmptyMessageDelayed(
- MESSAGE_RESTART_BLUETOOTH_SERVICE, getServiceRestartMs());
+ if (Flags.enableBleWhileDisablingAirplane()) {
+ if (mHandler.hasMessages(0, ON_AIRPLANE_MODE_CHANGED_TOKEN)) {
+ mHandler.removeCallbacksAndMessages(ON_AIRPLANE_MODE_CHANGED_TOKEN);
+ Log.d(TAG, "Handling delayed airplane mode event");
+ handleAirplaneModeChanged(AirplaneModeListener.isOnOverrode());
+ }
+ if (mEnable && !isBinding()) {
+ Log.d(TAG, "Entering STATE_OFF but mEnabled is true; restarting.");
+ if (!Flags.systemServerRemoveExtraThreadJump()) {
+ waitForState(STATE_OFF);
+ }
+ mHandler.sendEmptyMessageDelayed(
+ MESSAGE_RESTART_BLUETOOTH_SERVICE, getServiceRestartMs());
+ }
+ } else {
+ if (mEnable) {
+ Log.d(TAG, "Entering STATE_OFF but mEnabled is true; restarting.");
+ if (!Flags.systemServerRemoveExtraThreadJump()) {
+ waitForState(STATE_OFF);
+ }
+ mHandler.sendEmptyMessageDelayed(
+ MESSAGE_RESTART_BLUETOOTH_SERVICE, getServiceRestartMs());
+ }
}
}
if (newState == STATE_ON || newState == STATE_BLE_ON) {
@@ -1573,17 +1574,19 @@ class BluetoothManagerService {
return mHandler.hasMessages(MESSAGE_TIMEOUT_BIND);
}
- private void handleEnableMessage(int quietEnable, int isBle) {
+ private void handleEnableMessage(boolean quietEnable, boolean isBle) {
+ String logHeader = "handleEnableMessage(" + quietEnable + ", " + isBle + "): ";
if (mShutdownInProgress) {
- Log.d(TAG, "Skip Bluetooth Enable in device shutdown process");
+ Log.d(TAG, logHeader + "Skip Bluetooth Enable in device shutdown process");
return;
}
- if (mHandler.hasMessages(MESSAGE_HANDLE_DISABLE_DELAYED)
- || mHandler.hasMessages(MESSAGE_HANDLE_ENABLE_DELAYED)) {
+ if (!Flags.systemServerRemoveExtraThreadJump()
+ && (mHandler.hasMessages(MESSAGE_HANDLE_DISABLE_DELAYED)
+ || mHandler.hasMessages(MESSAGE_HANDLE_ENABLE_DELAYED))) {
// We are handling enable or disable right now, wait for it.
mHandler.sendMessageDelayed(
- mHandler.obtainMessage(MESSAGE_ENABLE, quietEnable, isBle),
+ mHandler.obtainMessage(MESSAGE_ENABLE, quietEnable ? 1 : 0, isBle ? 1 : 0),
ENABLE_DISABLE_DELAY_MS);
return;
}
@@ -1591,27 +1594,27 @@ class BluetoothManagerService {
mHandler.removeMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE);
mEnable = true;
- if (isBle == 0) {
+ if (!isBle) {
setBluetoothPersistedState(BLUETOOTH_ON_BLUETOOTH);
}
if (mState.oneOf(STATE_BLE_TURNING_ON, STATE_TURNING_ON, STATE_ON)) {
- Log.i(TAG, "MESSAGE_ENABLE: already enabled. Current state=" + mState);
+ Log.i(TAG, logHeader + "Already enabled. Current state=" + mState);
return;
}
- if (mState.oneOf(STATE_BLE_ON) && isBle == 1) {
- Log.i(TAG, "MESSAGE_ENABLE: Already in BLE_ON while being requested to go to BLE_ON");
+ if (mState.oneOf(STATE_BLE_ON) && isBle) {
+ Log.i(TAG, logHeader + "Already in BLE_ON while being requested to go to BLE_ON");
return;
}
if (mState.oneOf(STATE_BLE_ON)) {
- Log.i(TAG, "MESSAGE_ENABLE: Bluetooth transition from STATE_BLE_ON to STATE_ON");
+ Log.i(TAG, logHeader + "Bluetooth transition from STATE_BLE_ON to STATE_ON");
bleOnToOn();
return;
}
- if (mAdapter != null) {
+ if (!Flags.systemServerRemoveExtraThreadJump() && mAdapter != null) {
// TODO: b/339548431 - Adapt this after removal of Flags.explicitKillFromSystemServer
//
// We need to wait until transitioned to STATE_OFF and the previous Bluetooth process
@@ -1630,14 +1633,15 @@ class BluetoothManagerService {
return;
}
- mQuietEnable = (quietEnable == 1);
+ mQuietEnable = quietEnable;
handleEnable();
}
private void handleDisableMessage() {
- if (mHandler.hasMessages(MESSAGE_HANDLE_DISABLE_DELAYED)
- || isBinding()
- || mHandler.hasMessages(MESSAGE_HANDLE_ENABLE_DELAYED)) {
+ if (!Flags.systemServerRemoveExtraThreadJump()
+ && (mHandler.hasMessages(MESSAGE_HANDLE_DISABLE_DELAYED)
+ || isBinding()
+ || mHandler.hasMessages(MESSAGE_HANDLE_ENABLE_DELAYED))) {
// We are handling enable or disable right now, wait for it.
mHandler.sendEmptyMessageDelayed(MESSAGE_DISABLE, ENABLE_DISABLE_DELAY_MS);
return;
@@ -1645,10 +1649,25 @@ class BluetoothManagerService {
mHandler.removeMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE);
- if (mEnable && mAdapter != null) {
+ if (Flags.systemServerRemoveExtraThreadJump() && isBinding()) {
+ Log.d(TAG, "Disable while binding");
+ mEnable = false;
+ mContext.unbindService(mConnection);
+ mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
+ mHandler.removeMessages(MESSAGE_BLUETOOTH_SERVICE_CONNECTED);
+ } else if (Flags.systemServerRemoveExtraThreadJump()
+ && mState.oneOf(STATE_BLE_TURNING_ON)) {
+ Log.d(TAG, "Disable while BLE_TURNING_ON");
+ mEnable = false;
+ bluetoothStateChangeHandler(STATE_BLE_TURNING_ON, STATE_OFF);
+ } else if (mEnable && mAdapter != null) {
mWaitForDisableRetry = 0;
- mHandler.sendEmptyMessageDelayed(
- MESSAGE_HANDLE_DISABLE_DELAYED, ENABLE_DISABLE_DELAY_MS);
+ if (Flags.systemServerRemoveExtraThreadJump()) {
+ handleDisableDelayed(false);
+ } else {
+ mHandler.sendEmptyMessageDelayed(
+ MESSAGE_HANDLE_DISABLE_DELAYED, ENABLE_DISABLE_DELAY_MS);
+ }
} else {
mEnable = false;
onToBleOn();
@@ -1685,6 +1704,75 @@ class BluetoothManagerService {
}
}
+ private void handleEnableDelayed() {
+ // The Bluetooth is turning off, wait for STATE_OFF
+ if (!mState.oneOf(STATE_OFF)) {
+ if (mWaitForEnableRetry < MAX_WAIT_FOR_ENABLE_DISABLE_RETRIES) {
+ mWaitForEnableRetry++;
+ mHandler.sendEmptyMessageDelayed(
+ MESSAGE_HANDLE_ENABLE_DELAYED, ENABLE_DISABLE_DELAY_MS);
+ return;
+ } else {
+ Log.e(TAG, "Wait for STATE_OFF timeout");
+ }
+ }
+ if (Flags.systemServerRemoveExtraThreadJump()) {
+ handleEnable();
+ return;
+ }
+ // Either state is changed to STATE_OFF or reaches the maximum retry, we
+ // should move forward to the next step.
+ mWaitForEnableRetry = 0;
+ mHandler.sendEmptyMessageDelayed(MESSAGE_RESTART_BLUETOOTH_SERVICE, getServiceRestartMs());
+ Log.d(TAG, "Handle enable is finished");
+ }
+
+ private void handleDisableDelayed(boolean disabling) {
+ if (Flags.systemServerRemoveExtraThreadJump() && disabling) {
+ return;
+ }
+ if (!disabling) {
+ // The Bluetooth is turning on, wait for STATE_ON
+ if (!mState.oneOf(STATE_ON)) {
+ if (mWaitForDisableRetry < MAX_WAIT_FOR_ENABLE_DISABLE_RETRIES) {
+ mWaitForDisableRetry++;
+ mHandler.sendEmptyMessageDelayed(
+ MESSAGE_HANDLE_DISABLE_DELAYED, ENABLE_DISABLE_DELAY_MS);
+ return;
+ } else {
+ Log.e(TAG, "Wait for STATE_ON timeout");
+ }
+ }
+ // Either state is changed to STATE_ON or reaches the maximum retry, we
+ // should move forward to the next step.
+ mWaitForDisableRetry = 0;
+ mEnable = false;
+ onToBleOn();
+ if (!Flags.systemServerRemoveExtraThreadJump()) {
+ // Wait for state exiting STATE_ON
+ Message disableDelayedMsg =
+ mHandler.obtainMessage(MESSAGE_HANDLE_DISABLE_DELAYED, 1, 0);
+ mHandler.sendMessageDelayed(disableDelayedMsg, ENABLE_DISABLE_DELAY_MS);
+ }
+ } else {
+ // The Bluetooth is turning off, wait for exiting STATE_ON
+ if (mState.oneOf(STATE_ON)) {
+ if (mWaitForDisableRetry < MAX_WAIT_FOR_ENABLE_DISABLE_RETRIES) {
+ mWaitForDisableRetry++;
+ Message disableDelayedMsg =
+ mHandler.obtainMessage(MESSAGE_HANDLE_DISABLE_DELAYED, 1, 0);
+ mHandler.sendMessageDelayed(disableDelayedMsg, ENABLE_DISABLE_DELAY_MS);
+ return;
+ } else {
+ Log.e(TAG, "Wait for exiting STATE_ON timeout");
+ }
+ }
+ // Either state is exited from STATE_ON or reaches the maximum retry, we
+ // should move forward to the next step.
+ Log.d(TAG, "Handle disable is finished");
+ }
+ }
+
private void offToBleOn() {
if (!mState.oneOf(STATE_OFF)) {
Log.e(TAG, "offToBleOn: Impossible transition from " + mState);
@@ -1826,8 +1914,13 @@ class BluetoothManagerService {
}
private void sendDisableMsg(int reason, String packageName) {
- mHandler.sendEmptyMessage(MESSAGE_DISABLE);
+ if (!Flags.systemServerRemoveExtraThreadJump()) {
+ mHandler.sendEmptyMessage(MESSAGE_DISABLE);
+ }
ActiveLogs.add(reason, false, packageName, false);
+ if (Flags.systemServerRemoveExtraThreadJump()) {
+ handleDisableMessage();
+ }
}
private void sendEnableMsg(boolean quietMode, int reason) {
@@ -1839,9 +1932,14 @@ class BluetoothManagerService {
}
private void sendEnableMsg(boolean quietMode, int reason, String packageName, boolean isBle) {
- mHandler.obtainMessage(MESSAGE_ENABLE, quietMode ? 1 : 0, isBle ? 1 : 0).sendToTarget();
+ if (!Flags.systemServerRemoveExtraThreadJump()) {
+ mHandler.obtainMessage(MESSAGE_ENABLE, quietMode ? 1 : 0, isBle ? 1 : 0).sendToTarget();
+ }
ActiveLogs.add(reason, true, packageName, isBle);
mLastEnabledTime = SystemClock.elapsedRealtime();
+ if (Flags.systemServerRemoveExtraThreadJump()) {
+ handleEnableMessage(quietMode, isBle);
+ }
}
private void addCrashLog() {
@@ -1997,10 +2095,6 @@ class BluetoothManagerService {
}
void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
- if ((args.length > 0) && args[0].startsWith("--proto")) {
- dumpProto(fd);
- return;
- }
String errorMsg = null;
writer.println("Bluetooth Status");
@@ -2090,33 +2184,6 @@ class BluetoothManagerService {
});
}
- private void dumpProto(FileDescriptor fd) {
- final ProtoOutputStream proto = new ProtoOutputStream(new FileOutputStream(fd));
- proto.write(BluetoothManagerServiceDumpProto.ENABLED, isEnabled());
- proto.write(BluetoothManagerServiceDumpProto.STATE, mState.get());
- proto.write(BluetoothManagerServiceDumpProto.STATE_NAME, nameForState(mState.get()));
- proto.write(BluetoothManagerServiceDumpProto.ADDRESS, logAddress(mAddress));
- proto.write(BluetoothManagerServiceDumpProto.NAME, mName);
- if (mEnable) {
- proto.write(BluetoothManagerServiceDumpProto.LAST_ENABLED_TIME_MS, mLastEnabledTime);
- }
- proto.write(
- BluetoothManagerServiceDumpProto.CURR_TIMESTAMP_MS, SystemClock.elapsedRealtime());
- ActiveLogs.dumpProto(proto);
- proto.write(BluetoothManagerServiceDumpProto.NUM_CRASHES, mCrashes);
- proto.write(
- BluetoothManagerServiceDumpProto.CRASH_LOG_MAXED, mCrashes == CRASH_LOG_MAX_SIZE);
- for (Long time : mCrashTimestamps) {
- proto.write(BluetoothManagerServiceDumpProto.CRASH_TIMESTAMPS_MS, time);
- }
- proto.write(BluetoothManagerServiceDumpProto.NUM_BLE_APPS, mBleApps.size());
- for (ClientDeathRecipient app : mBleApps.values()) {
- proto.write(
- BluetoothManagerServiceDumpProto.BLE_APP_PACKAGE_NAMES, app.getPackageName());
- }
- proto.flush();
- }
-
static @NonNull Bundle getTempAllowlistBroadcastOptions() {
final long duration = 10_000;
final BroadcastOptions bOptions = BroadcastOptions.makeBasic();
@@ -2274,33 +2341,34 @@ class BluetoothManagerService {
}
/**
- * In case of a Bluetooth crash, mark it's enabled components as non longer available to
- * trigger the PACKAGE_CHANGED intent. This should not be needed in a normal shutdown as the
- * Bluetooth clean its components on its own
+ * In case of a Bluetooth crash, mark it's enabled components as non longer available to trigger
+ * the PACKAGE_CHANGED intent. This should not be needed in a normal shutdown as the Bluetooth
+ * clean its components on its own
*/
private void disableBluetoothComponents(String packageName) {
PackageManager pm = mContext.getPackageManager();
PackageInfo packageInfo = null;
try {
- packageInfo = pm.getPackageInfo(
- packageName,
- PackageManager.GET_SERVICES |
- PackageManager.GET_ACTIVITIES |
- PackageManager.GET_RECEIVERS |
- PackageManager.GET_PROVIDERS);
+ packageInfo =
+ pm.getPackageInfo(
+ packageName,
+ PackageManager.GET_SERVICES
+ | PackageManager.GET_ACTIVITIES
+ | PackageManager.GET_RECEIVERS
+ | PackageManager.GET_PROVIDERS);
} catch (PackageManager.NameNotFoundException e) {
Log.e(TAG, "Package not found: " + packageName, e);
return;
}
// Refer to updateOppLauncherComponentState()
- List<String> baseBluetoothOppActivities = List.of(
- "com.android.bluetooth.opp.BluetoothOppLauncherActivity",
- "com.android.bluetooth.opp.BluetoothOppBtEnableActivity",
- "com.android.bluetooth.opp.BluetoothOppBtEnablingActivity",
- "com.android.bluetooth.opp.BluetoothOppBtErrorActivity"
- );
+ List<String> baseBluetoothOppActivities =
+ List.of(
+ "com.android.bluetooth.opp.BluetoothOppLauncherActivity",
+ "com.android.bluetooth.opp.BluetoothOppBtEnableActivity",
+ "com.android.bluetooth.opp.BluetoothOppBtEnablingActivity",
+ "com.android.bluetooth.opp.BluetoothOppBtErrorActivity");
disableComponents(pm, packageInfo.activities, packageName, baseBluetoothOppActivities);
disableComponents(pm, packageInfo.services, packageName, null);
@@ -2315,17 +2383,20 @@ class BluetoothManagerService {
}
Arrays.stream(components)
- .filter(componentInfo -> !componentInfo.enabled)
- .map(componentInfo -> new ComponentName(packageName, componentInfo.name))
- .filter(componentName ->
- (componentsToKeep == null ||
- !componentsToKeep.contains(componentName.getClassName())))
- .forEach(componentName -> {
- pm.setComponentEnabledSetting(
- componentName,
- PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
- PackageManager.DONT_KILL_APP);
- Log.i(TAG, "Disabled component: " + componentName.flattenToString());
- });
+ .filter(componentInfo -> !componentInfo.enabled)
+ .map(componentInfo -> new ComponentName(packageName, componentInfo.name))
+ .filter(
+ componentName ->
+ (componentsToKeep == null
+ || !componentsToKeep.contains(
+ componentName.getClassName())))
+ .forEach(
+ componentName -> {
+ pm.setComponentEnabledSetting(
+ componentName,
+ PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
+ PackageManager.DONT_KILL_APP);
+ Log.i(TAG, "Disabled component: " + componentName.flattenToString());
+ });
}
}
diff --git a/service/tests/Android.bp b/service/tests/Android.bp
index 217bd36f70..8bdefcc8ac 100644
--- a/service/tests/Android.bp
+++ b/service/tests/Android.bp
@@ -26,6 +26,7 @@ android_test {
],
static_libs: [
+ "androidx.test.espresso.intents",
"androidx.test.rules",
"flag-junit",
"frameworks-base-testutils",
diff --git a/service/tests/src/com/android/server/bluetooth/BluetoothManagerServiceTest.java b/service/tests/src/com/android/server/bluetooth/BluetoothManagerServiceTest.java
index 480af98329..e825940e90 100644
--- a/service/tests/src/com/android/server/bluetooth/BluetoothManagerServiceTest.java
+++ b/service/tests/src/com/android/server/bluetooth/BluetoothManagerServiceTest.java
@@ -22,6 +22,9 @@ import static android.bluetooth.BluetoothAdapter.STATE_ON;
import static android.bluetooth.BluetoothAdapter.STATE_TURNING_OFF;
import static android.bluetooth.BluetoothAdapter.STATE_TURNING_ON;
+import static androidx.test.espresso.intent.matcher.IntentMatchers.hasAction;
+import static androidx.test.espresso.intent.matcher.IntentMatchers.hasExtra;
+
import static com.android.server.bluetooth.BluetoothManagerService.MESSAGE_BLUETOOTH_SERVICE_CONNECTED;
import static com.android.server.bluetooth.BluetoothManagerService.MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED;
import static com.android.server.bluetooth.BluetoothManagerService.MESSAGE_BLUETOOTH_STATE_CHANGE;
@@ -33,6 +36,7 @@ import static com.android.server.bluetooth.BluetoothManagerService.MESSAGE_RESTO
import static com.android.server.bluetooth.BluetoothManagerService.MESSAGE_TIMEOUT_BIND;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.eq;
@@ -41,13 +45,16 @@ import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.validateMockitoUsage;
import static org.mockito.Mockito.verify;
import android.annotation.SuppressLint;
+import android.app.AppOpsManager;
import android.app.PropertyInvalidatedCache;
+import android.bluetooth.BluetoothAdapter;
import android.bluetooth.IBluetooth;
import android.bluetooth.IBluetoothCallback;
import android.bluetooth.IBluetoothManager;
@@ -55,7 +62,6 @@ import android.bluetooth.IBluetoothManagerCallback;
import android.bluetooth.IBluetoothStateChangeCallback;
import android.content.ComponentName;
import android.content.Context;
-import android.content.ContextWrapper;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
@@ -63,21 +69,29 @@ import android.os.Message;
import android.os.UserHandle;
import android.os.UserManager;
import android.os.test.TestLooper;
+import android.permission.PermissionManager;
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.annotations.EnableFlags;
import android.platform.test.flag.junit.FlagsParameterization;
import android.platform.test.flag.junit.SetFlagsRule;
import android.provider.Settings;
import androidx.test.platform.app.InstrumentationRegistry;
+import com.android.bluetooth.flags.Flags;
+
+import org.hamcrest.Matcher;
+import org.hamcrest.core.AllOf;
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.InOrder;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-import org.mockito.Spy;
+import org.mockito.hamcrest.MockitoHamcrest;
import platform.test.runner.parameterized.ParameterizedAndroidJunit4;
import platform.test.runner.parameterized.Parameters;
@@ -93,7 +107,8 @@ public class BluetoothManagerServiceTest {
@Parameters(name = "{0}")
public static List<FlagsParameterization> getParams() {
- return FlagsParameterization.allCombinationsOf();
+ return FlagsParameterization.allCombinationsOf(
+ Flags.FLAG_SYSTEM_SERVER_REMOVE_EXTRA_THREAD_JUMP);
}
public BluetoothManagerServiceTest(FlagsParameterization flags) {
@@ -103,24 +118,26 @@ public class BluetoothManagerServiceTest {
private static final int STATE_BLE_TURNING_ON = 14; // can't find the symbol because hidden api
private static final int STATE_BLE_TURNING_OFF = 16; // can't find the symbol because hidden api
- BluetoothManagerService mManagerService;
+ private final Context mTargetContext =
+ InstrumentationRegistry.getInstrumentation().getTargetContext();
- @Spy
- private final Context mContext =
- new ContextWrapper(InstrumentationRegistry.getInstrumentation().getTargetContext());
-
- @Spy BluetoothServerProxy mBluetoothServerProxy;
+ @Mock BluetoothServerProxy mBluetoothServerProxy;
+ @Mock Context mContext;
@Mock UserManager mUserManager;
@Mock UserHandle mUserHandle;
-
@Mock IBinder mBinder;
@Mock IBluetoothManagerCallback mManagerCallback;
@Mock IBluetoothStateChangeCallback mStateChangeCallback;
-
@Mock IBluetooth mAdapterService;
@Mock AdapterBinder mAdapterBinder;
+ @Mock AppOpsManager mAppOpsManager;
+ @Mock PermissionManager mPermissionManager;
+
+ private int mPersistedState = BluetoothManagerService.BLUETOOTH_OFF;
- TestLooper mLooper;
+ private InOrder mInOrder;
+ private TestLooper mLooper;
+ private BluetoothManagerService mManagerService;
private static class ServerQuery
extends PropertyInvalidatedCache.QueryHandler<IBluetoothManager, Integer> {
@@ -146,6 +163,7 @@ public class BluetoothManagerServiceTest {
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
+ mInOrder = inOrder(mContext, mManagerCallback, mAdapterBinder);
PropertyInvalidatedCache<IBluetoothManager, Integer> testCache =
new PropertyInvalidatedCache<>(
@@ -163,24 +181,37 @@ public class BluetoothManagerServiceTest {
doReturn("00:11:22:33:44:55")
.when(mBluetoothServerProxy)
.settingsSecureGetString(any(), eq(Settings.Secure.BLUETOOTH_ADDRESS));
- // Set persisted state to BLUETOOTH_OFF to not generate unwanted behavior when starting test
- doReturn(BluetoothManagerService.BLUETOOTH_OFF)
+ doAnswer(
+ inv -> {
+ return mPersistedState;
+ })
.when(mBluetoothServerProxy)
.getBluetoothPersistedState(any(), anyInt());
doAnswer(
inv -> {
- doReturn(inv.getArguments()[1])
- .when(mBluetoothServerProxy)
- .getBluetoothPersistedState(any(), anyInt());
+ mPersistedState = inv.getArgument(1);
return null;
})
.when(mBluetoothServerProxy)
.setBluetoothPersistedState(any(), anyInt());
- // Test is not allowed to send broadcast as Bluetooth. doNothing Prevent SecurityException
- doNothing().when(mContext).sendBroadcastAsUser(any(), any(), any(), any());
+ doAnswer(
+ inv -> {
+ IBinder.DeathRecipient recipient = inv.getArgument(0);
+ recipient.binderDied();
+ return null;
+ })
+ .when(mBinder)
+ .linkToDeath(any(), anyInt());
+
+ doReturn(BluetoothManagerServiceTest.class.getSimpleName()).when(mContext).getPackageName();
+ doReturn(mContext).when(mContext).createContextAsUser(any(), anyInt());
+ doReturn(mTargetContext.getContentResolver()).when(mContext).getContentResolver();
+ doReturn(mTargetContext.getPackageManager()).when(mContext).getPackageManager();
doReturn(mUserManager).when(mContext).getSystemService(UserManager.class);
+ doReturn(mAppOpsManager).when(mContext).getSystemService(AppOpsManager.class);
+ doReturn(mPermissionManager).when(mContext).getSystemService(PermissionManager.class);
doReturn(mBinder).when(mManagerCallback).asBinder();
@@ -233,9 +264,13 @@ public class BluetoothManagerServiceTest {
IntStream.of(what)
.forEach(
w -> {
+ String log = "Expecting message " + w + ": ";
+
Message msg = mLooper.nextMessage();
- assertThat(msg).isNotNull();
- assertThat(msg.what).isEqualTo(w);
+ assertWithMessage(log + "but got null").that(msg).isNotNull();
+ assertWithMessage(log + "but got " + msg.what)
+ .that(msg.what)
+ .isEqualTo(w);
msg.getTarget().dispatchMessage(msg);
});
}
@@ -270,7 +305,9 @@ public class BluetoothManagerServiceTest {
// called from SYSTEM user, should try to toggle Bluetooth off
mManagerService.onUserRestrictionsChanged(UserHandle.SYSTEM);
- syncHandler(MESSAGE_DISABLE);
+ if (!Flags.systemServerRemoveExtraThreadJump()) {
+ syncHandler(MESSAGE_DISABLE);
+ }
}
@Test
@@ -283,8 +320,11 @@ public class BluetoothManagerServiceTest {
anyInt(),
any(UserHandle.class));
mManagerService.enableBle("enable_bindFailure_removesTimeout", mBinder);
- syncHandler(MESSAGE_ENABLE);
+ if (!Flags.systemServerRemoveExtraThreadJump()) {
+ syncHandler(MESSAGE_ENABLE);
+ }
verify(mContext).unbindService(any());
+ mInOrder.verify(mContext).unbindService(any());
// TODO(b/280518177): Failed to start should be noted / reported in metrics
// Maybe show a popup or a crash notification
@@ -294,7 +334,9 @@ public class BluetoothManagerServiceTest {
@Test
public void enable_bindTimeout() throws Exception {
mManagerService.enableBle("enable_bindTimeout", mBinder);
- syncHandler(MESSAGE_ENABLE);
+ if (!Flags.systemServerRemoveExtraThreadJump()) {
+ syncHandler(MESSAGE_ENABLE);
+ }
mLooper.moveTimeForward(120_000); // 120 seconds
syncHandler(MESSAGE_TIMEOUT_BIND);
@@ -312,7 +354,7 @@ public class BluetoothManagerServiceTest {
ArgumentCaptor<BluetoothManagerService.BluetoothServiceConnection> captor =
ArgumentCaptor.forClass(BluetoothManagerService.BluetoothServiceConnection.class);
- verify(mContext)
+ mInOrder.verify(mContext)
.bindServiceAsUser(
any(Intent.class), captor.capture(), anyInt(), any(UserHandle.class));
assertThat(captor.getAllValues()).hasSize(1);
@@ -324,11 +366,10 @@ public class BluetoothManagerServiceTest {
return serviceConnection;
}
- private static IBluetoothCallback captureBluetoothCallback(AdapterBinder adapterBinder)
- throws Exception {
+ private IBluetoothCallback captureBluetoothCallback() throws Exception {
ArgumentCaptor<IBluetoothCallback> captor =
ArgumentCaptor.forClass(IBluetoothCallback.class);
- verify(adapterBinder).registerCallback(captor.capture(), any());
+ mInOrder.verify(mAdapterBinder).registerCallback(captor.capture(), any());
assertThat(captor.getAllValues()).hasSize(1);
return captor.getValue();
}
@@ -337,11 +378,10 @@ public class BluetoothManagerServiceTest {
// Binding of IBluetooth
acceptBluetoothBinding();
- // TODO(b/280518177): This callback is too early, bt is not ON nor BLE_ON
- verify(mManagerCallback).onBluetoothServiceUp(any());
-
- IBluetoothCallback btCallback = captureBluetoothCallback(mAdapterBinder);
- verify(mAdapterBinder).offToBleOn(anyBoolean(), any());
+ IBluetoothCallback btCallback = captureBluetoothCallback();
+ mInOrder.verify(mAdapterBinder).offToBleOn(anyBoolean(), any());
+ verifyBleStateIntentSent(STATE_OFF, STATE_BLE_TURNING_ON);
+ mInOrder.verify(mManagerCallback).onBluetoothServiceUp(any());
assertThat(mManagerService.getState()).isEqualTo(STATE_BLE_TURNING_ON);
@@ -349,30 +389,30 @@ public class BluetoothManagerServiceTest {
// trigger the stateChangeCallback from native
btCallback.onBluetoothStateChange(STATE_BLE_TURNING_ON, STATE_BLE_ON);
syncHandler(MESSAGE_BLUETOOTH_STATE_CHANGE);
+ verifyBleStateIntentSent(STATE_BLE_TURNING_ON, STATE_BLE_ON);
return btCallback;
}
private IBluetoothCallback transition_offToOn() throws Exception {
IBluetoothCallback btCallback = transition_offToBleOn();
- verify(mAdapterBinder).bleOnToOn(any());
+ mInOrder.verify(mAdapterBinder).bleOnToOn(any());
// AdapterService go to turning_on and start all profile on its own
btCallback.onBluetoothStateChange(STATE_BLE_ON, STATE_TURNING_ON);
syncHandler(MESSAGE_BLUETOOTH_STATE_CHANGE);
+ verifyBleStateIntentSent(STATE_BLE_ON, STATE_TURNING_ON);
+ verifyStateIntentSent(STATE_OFF, STATE_TURNING_ON);
// When all the profile are started, adapterService consider it is ON
btCallback.onBluetoothStateChange(STATE_TURNING_ON, STATE_ON);
syncHandler(MESSAGE_BLUETOOTH_STATE_CHANGE);
-
- // Check that we sent 6 intent, 4 for BLE: BLE_TURNING_ON + BLE_ON + TURNING_ON + ON
- // and 2 for classic: TURNING_ON + ON
- // TODO(b/280518177): assert the intent are the correct one
- verify(mContext, times(6)).sendBroadcastAsUser(any(), any(), any(), any());
+ verifyBleStateIntentSent(STATE_TURNING_ON, STATE_ON);
+ verifyStateIntentSent(STATE_TURNING_ON, STATE_ON);
return btCallback;
}
private void transition_onToBleOn(IBluetoothCallback btCallback) throws Exception {
- verify(mAdapterBinder).onToBleOn(any());
+ mInOrder.verify(mAdapterBinder).onToBleOn(any());
btCallback.onBluetoothStateChange(STATE_TURNING_OFF, STATE_BLE_ON);
syncHandler(MESSAGE_BLUETOOTH_STATE_CHANGE);
@@ -380,7 +420,7 @@ public class BluetoothManagerServiceTest {
private void transition_onToOff(IBluetoothCallback btCallback) throws Exception {
transition_onToBleOn(btCallback);
- verify(mAdapterBinder).bleOnToOff(any());
+ mInOrder.verify(mAdapterBinder).bleOnToOff(any());
// When all the profile are started, adapterService consider it is ON
btCallback.onBluetoothStateChange(STATE_BLE_TURNING_OFF, STATE_OFF);
@@ -390,62 +430,70 @@ public class BluetoothManagerServiceTest {
@Test
public void enable_whileTurningToBleOn_shouldEnable() throws Exception {
mManagerService.enableBle("enable_whileTurningToBleOn_shouldEnable", mBinder);
- syncHandler(MESSAGE_ENABLE);
+ if (!Flags.systemServerRemoveExtraThreadJump()) {
+ syncHandler(MESSAGE_ENABLE);
+ }
acceptBluetoothBinding();
- IBluetoothCallback btCallback = captureBluetoothCallback(mAdapterBinder);
+ IBluetoothCallback btCallback = captureBluetoothCallback();
assertThat(mManagerService.getState()).isEqualTo(STATE_BLE_TURNING_ON);
// receive enable when Bluetooth is in BLE_TURNING_ON
mManagerService.enable("enable_whileTurningToBleOn_shouldEnable");
- syncHandler(MESSAGE_ENABLE);
+ if (!Flags.systemServerRemoveExtraThreadJump()) {
+ syncHandler(MESSAGE_ENABLE);
+ }
btCallback.onBluetoothStateChange(STATE_BLE_TURNING_ON, STATE_BLE_ON);
syncHandler(MESSAGE_BLUETOOTH_STATE_CHANGE);
- verify(mAdapterBinder).bleOnToOn(any());
+ mInOrder.verify(mAdapterBinder).bleOnToOn(any());
}
@Test
public void enable_whileNotYetBoundToBle_shouldEnable() throws Exception {
mManagerService.enableBle("enable_whileTurningToBleOn_shouldEnable", mBinder);
- syncHandler(MESSAGE_ENABLE);
+ if (!Flags.systemServerRemoveExtraThreadJump()) {
+ syncHandler(MESSAGE_ENABLE);
+ }
assertThat(mManagerService.getState()).isEqualTo(STATE_OFF);
// receive enable when Bluetooth is OFF and not yet binded
mManagerService.enable("enable_whileTurningToBleOn_shouldEnable");
- syncHandler(MESSAGE_ENABLE);
+ if (!Flags.systemServerRemoveExtraThreadJump()) {
+ syncHandler(MESSAGE_ENABLE);
+ }
acceptBluetoothBinding();
- IBluetoothCallback btCallback = captureBluetoothCallback(mAdapterBinder);
+ IBluetoothCallback btCallback = captureBluetoothCallback();
assertThat(mManagerService.getState()).isEqualTo(STATE_BLE_TURNING_ON);
btCallback.onBluetoothStateChange(STATE_BLE_TURNING_ON, STATE_BLE_ON);
syncHandler(MESSAGE_BLUETOOTH_STATE_CHANGE);
- verify(mAdapterBinder).bleOnToOn(any());
+ mInOrder.verify(mAdapterBinder).bleOnToOn(any());
}
@Test
public void offToBleOn() throws Exception {
mManagerService.enableBle("test_offToBleOn", mBinder);
- syncHandler(MESSAGE_ENABLE);
+ if (!Flags.systemServerRemoveExtraThreadJump()) {
+ syncHandler(MESSAGE_ENABLE);
+ }
transition_offToBleOn();
- // Check that we sent 2 intent, one for BLE_TURNING_ON, one for BLE_ON
- // TODO(b/280518177): assert the intent are the correct one
- verify(mContext, times(2)).sendBroadcastAsUser(any(), any(), any(), any());
-
// Check that there was no transition to STATE_ON
- verify(mAdapterBinder, times(0)).bleOnToOn(any());
+ mInOrder.verify(mAdapterBinder, never()).bleOnToOn(any());
assertThat(mManagerService.getState()).isEqualTo(STATE_BLE_ON);
}
@Test
public void offToOn() throws Exception {
mManagerService.enable("test_offToOn");
- syncHandler(MESSAGE_ENABLE);
+ if (!Flags.systemServerRemoveExtraThreadJump()) {
+ syncHandler(MESSAGE_ENABLE);
+ }
transition_offToOn();
@@ -455,13 +503,15 @@ public class BluetoothManagerServiceTest {
@Test
public void crash_whileTransitionState_canRecover() throws Exception {
mManagerService.enableBle("crash_whileTransitionState_canRecover", mBinder);
- syncHandler(MESSAGE_ENABLE);
+ if (!Flags.systemServerRemoveExtraThreadJump()) {
+ syncHandler(MESSAGE_ENABLE);
+ }
BluetoothManagerService.BluetoothServiceConnection serviceConnection =
acceptBluetoothBinding();
- IBluetoothCallback btCallback = captureBluetoothCallback(mAdapterBinder);
- verify(mAdapterBinder).offToBleOn(anyBoolean(), any());
+ IBluetoothCallback btCallback = captureBluetoothCallback();
+ mInOrder.verify(mAdapterBinder).offToBleOn(anyBoolean(), any());
btCallback.onBluetoothStateChange(STATE_OFF, STATE_BLE_TURNING_ON);
syncHandler(MESSAGE_BLUETOOTH_STATE_CHANGE);
assertThat(mManagerService.getState()).isEqualTo(STATE_BLE_TURNING_ON);
@@ -484,42 +534,136 @@ public class BluetoothManagerServiceTest {
@Test
public void disableAirplane_whenNothing_startBluetooth() throws Exception {
- doReturn(BluetoothManagerService.BLUETOOTH_ON_BLUETOOTH)
- .when(mBluetoothServerProxy)
- .getBluetoothPersistedState(any(), anyInt());
+ if (!Flags.systemServerRemoveExtraThreadJump()) {
+ mPersistedState = BluetoothManagerService.BLUETOOTH_ON_BLUETOOTH;
+ }
mManagerService.enable("disableAirplane_whenNothing_startBluetooth");
- discardMessage(MESSAGE_ENABLE);
+ if (!Flags.systemServerRemoveExtraThreadJump()) {
+ discardMessage(MESSAGE_ENABLE);
+ } else {
+ transition_offToOn();
+ }
+
+ assertThat(mLooper.nextMessage()).isNull();
mManagerService.onAirplaneModeChanged(false);
- discardMessage(MESSAGE_ENABLE);
+ if (!Flags.systemServerRemoveExtraThreadJump()) {
+ discardMessage(MESSAGE_ENABLE);
+ }
}
@Test
- public void disableAirplane_whenFactoryReset_doesNotStartBluetooth() throws Exception {
- doAnswer(
- invocation -> {
- IBinder.DeathRecipient recipient = invocation.getArgument(0);
- recipient.binderDied();
- return null;
- })
- .when(mBinder)
- .linkToDeath(any(), anyInt());
+ @EnableFlags(Flags.FLAG_SYSTEM_SERVER_REMOVE_EXTRA_THREAD_JUMP)
+ public void disable_whenBinding_bluetoothShouldStop_new() throws Exception {
+ mManagerService.enable("disable_whenBinding_bluetoothShouldStop_new");
+ mInOrder.verify(mContext).bindServiceAsUser(any(), any(), anyInt(), any());
+ mManagerService.disable("disable_whenBinding_bluetoothShouldStop_new", true);
+ mInOrder.verify(mContext).unbindService(any());
+ assertThat(mManagerService.getState()).isEqualTo(STATE_OFF);
+ }
- mManagerService.enable("test_offToOn");
+ @Test
+ @EnableFlags(Flags.FLAG_SYSTEM_SERVER_REMOVE_EXTRA_THREAD_JUMP)
+ public void disable_whenTurningBleOn_bluetoothShouldStop() throws Exception {
+ mManagerService.enable("disable_whenBinding_bluetoothShouldStop_new");
+ acceptBluetoothBinding();
+ assertThat(mManagerService.getState()).isEqualTo(STATE_BLE_TURNING_ON);
+ mManagerService.disable("disable_whenBinding_bluetoothShouldStop_new", true);
+ mInOrder.verify(mContext).unbindService(any());
+ assertThat(mManagerService.getState()).isEqualTo(STATE_OFF);
+ }
+
+ @Test
+ @DisableFlags(Flags.FLAG_SYSTEM_SERVER_REMOVE_EXTRA_THREAD_JUMP)
+ public void disable_whenBinding_bluetoothShouldStop_old() throws Exception {
+ mManagerService.enable("disable_whenBinding_bluetoothShouldStop_old");
syncHandler(MESSAGE_ENABLE);
+ mManagerService.disable("disable_whenBinding_bluetoothShouldStop_old", true);
+ syncHandler(MESSAGE_DISABLE);
+
+ IBluetoothCallback btCallback = transition_offToBleOn();
+ assertThat(mManagerService.getState()).isEqualTo(STATE_BLE_TURNING_OFF);
+
+ btCallback.onBluetoothStateChange(STATE_BLE_TURNING_OFF, STATE_OFF);
+ syncHandler(MESSAGE_BLUETOOTH_STATE_CHANGE);
+
+ mLooper.moveTimeForward(BluetoothManagerService.ENABLE_DISABLE_DELAY_MS);
+ syncHandler(MESSAGE_DISABLE);
+
+ assertThat(mManagerService.getState()).isEqualTo(STATE_OFF);
+ }
+
+ @Test
+ public void disableAirplane_whenFactoryReset_doesNotStartBluetooth() throws Exception {
+ mManagerService.enable("disableAirplane_whenFactoryReset_doesNotStartBluetooth");
+ if (!Flags.systemServerRemoveExtraThreadJump()) {
+ syncHandler(MESSAGE_ENABLE);
+ }
IBluetoothCallback btCallback = transition_offToOn();
assertThat(mManagerService.getState()).isEqualTo(STATE_ON);
mManagerService.mHandler.sendEmptyMessage(MESSAGE_RESTORE_USER_SETTING_OFF);
syncHandler(MESSAGE_RESTORE_USER_SETTING_OFF);
- syncHandler(MESSAGE_DISABLE);
- mLooper.moveTimeForward(BluetoothManagerService.ENABLE_DISABLE_DELAY_MS);
- syncHandler(MESSAGE_HANDLE_DISABLE_DELAYED);
- mLooper.moveTimeForward(BluetoothManagerService.ENABLE_DISABLE_DELAY_MS);
- syncHandler(MESSAGE_HANDLE_DISABLE_DELAYED);
+ if (!Flags.systemServerRemoveExtraThreadJump()) {
+ syncHandler(MESSAGE_DISABLE);
+ mLooper.moveTimeForward(BluetoothManagerService.ENABLE_DISABLE_DELAY_MS);
+ syncHandler(MESSAGE_HANDLE_DISABLE_DELAYED);
+ mLooper.moveTimeForward(BluetoothManagerService.ENABLE_DISABLE_DELAY_MS);
+ syncHandler(MESSAGE_HANDLE_DISABLE_DELAYED);
+ }
transition_onToOff(btCallback);
mManagerService.onAirplaneModeChanged(false);
assertThat(mLooper.nextMessage()).isNull(); // Must not create a MESSAGE_ENABLE
}
+
+ @Test
+ @EnableFlags({
+ Flags.FLAG_SYSTEM_SERVER_REMOVE_EXTRA_THREAD_JUMP,
+ Flags.FLAG_ENABLE_BLE_WHILE_DISABLING_AIRPLANE
+ })
+ public void enableBle_whenDisableAirplaneIsDelayed_startBluetooth() throws Exception {
+ mManagerService.enable("enableBle_whenDisableAirplaneIsDelayed_startBluetooth");
+ IBluetoothCallback btCallback = transition_offToOn();
+ mManagerService.onAirplaneModeChanged(true);
+ assertThat(mManagerService.getState()).isEqualTo(STATE_TURNING_OFF);
+
+ // Generate an event that will be delayed due to the TURNING_OFF state
+ mManagerService.onAirplaneModeChanged(false);
+
+ transition_onToBleOn(btCallback);
+ mInOrder.verify(mAdapterBinder).bleOnToOff(any());
+ assertThat(mManagerService.getState()).isEqualTo(STATE_BLE_TURNING_OFF);
+
+ // As soon as we left BLE_ON, generate a call from 3p app that request to turn on Bluetooth
+ mManagerService.enableBle("enableBle_whenDisableAirplaneIsDelayed_startBluetooth", mBinder);
+
+ // When all the profile are started, adapterService consider it is ON
+ btCallback.onBluetoothStateChange(STATE_BLE_TURNING_OFF, STATE_OFF);
+ syncHandler(MESSAGE_BLUETOOTH_STATE_CHANGE);
+
+ transition_offToOn();
+ assertThat(mManagerService.getState()).isEqualTo(STATE_ON);
+ }
+
+ @SafeVarargs
+ private void verifyIntentSent(Matcher<Intent>... matchers) {
+ mInOrder.verify(mContext)
+ .sendBroadcastAsUser(
+ MockitoHamcrest.argThat(AllOf.allOf(matchers)), any(), any(), any());
+ }
+
+ private void verifyBleStateIntentSent(int from, int to) {
+ verifyIntentSent(
+ hasAction(BluetoothAdapter.ACTION_BLE_STATE_CHANGED),
+ hasExtra(BluetoothAdapter.EXTRA_PREVIOUS_STATE, from),
+ hasExtra(BluetoothAdapter.EXTRA_STATE, to));
+ }
+
+ private void verifyStateIntentSent(int from, int to) {
+ verifyIntentSent(
+ hasAction(BluetoothAdapter.ACTION_STATE_CHANGED),
+ hasExtra(BluetoothAdapter.EXTRA_PREVIOUS_STATE, from),
+ hasExtra(BluetoothAdapter.EXTRA_STATE, to));
+ }
}
diff --git a/system/BUILD.gn b/system/BUILD.gn
index b86ca5f392..48b6207a60 100644
--- a/system/BUILD.gn
+++ b/system/BUILD.gn
@@ -76,7 +76,6 @@ config("target_defaults") {
"//bt/system",
"//bt/flags/exported_include",
"//bt/sysprop/exported_include",
- "//bt/system/linux_include",
"//bt/system/include",
"//bt/system/gd",
"//bt/system/pdl/hci/include",
diff --git a/system/audio_hal_interface/aidl/le_audio_software_aidl.cc b/system/audio_hal_interface/aidl/le_audio_software_aidl.cc
index be7cf3a6b2..e0b96475d3 100644
--- a/system/audio_hal_interface/aidl/le_audio_software_aidl.cc
+++ b/system/audio_hal_interface/aidl/le_audio_software_aidl.cc
@@ -30,6 +30,7 @@
#include "common/strings.h"
#include "hal_version_manager.h"
#include "le_audio_utils.h"
+#include "osi/include/properties.h"
namespace bluetooth {
namespace audio {
@@ -694,6 +695,14 @@ bluetooth::audio::le_audio::OffloadCapabilities get_offload_capabilities() {
return {offload_capabilities, broadcast_offload_capabilities};
}
+static bool IsUsingCodecExtensibility() {
+ auto codec_ext_status =
+ osi_property_get_bool("bluetooth.core.le_audio.codec_extension_aidl.enabled", false);
+
+ log::debug("Using codec extensibility AIDL: {}", codec_ext_status);
+ return codec_ext_status;
+}
+
AudioConfiguration stream_config_to_hal_audio_config(
const ::bluetooth::le_audio::stream_config& offload_config) {
LeAudioConfiguration ucast_config = {
@@ -726,6 +735,7 @@ AudioConfiguration stream_config_to_hal_audio_config(
.blocksPerSdu = static_cast<int8_t>(offload_config.codec_frames_blocks_per_sdu),
};
ucast_config.leAudioCodecConfig = LeAudioCodecConfiguration(lc3_config);
+ ucast_config.codecType = CodecType::LC3;
lc3_codec_config_found = true;
}
@@ -741,14 +751,20 @@ AudioConfiguration stream_config_to_hal_audio_config(
BLE_ADDRESS_RANDOM;
}
- ucast_config.streamMap.push_back({
+ LeAudioConfiguration::StreamMap map_entry = {
.streamHandle = info.stream_handle,
.audioChannelAllocation = static_cast<int32_t>(info.audio_channel_allocation),
.isStreamActive = info.is_stream_active,
- .aseConfiguration = GetAidlLeAudioAseConfigurationFromStackFormat(
- info.codec_config, info.target_latency, info.target_phy, info.metadata),
- .bluetoothDeviceAddress = aidl_device_address,
- });
+ };
+
+ // Add the additional codec extensibility data fields
+ if (IsUsingCodecExtensibility()) {
+ map_entry.aseConfiguration = GetAidlLeAudioAseConfigurationFromStackFormat(
+ info.codec_config, info.target_latency, info.target_phy, info.metadata);
+ map_entry.bluetoothDeviceAddress = aidl_device_address;
+ }
+
+ ucast_config.streamMap.push_back(map_entry);
}
if (!lc3_codec_config_found) {
diff --git a/system/bta/Android.bp b/system/bta/Android.bp
index 52d34d59cc..5a8f721ebd 100644
--- a/system/bta/Android.bp
+++ b/system/bta/Android.bp
@@ -231,6 +231,7 @@ cc_test {
":TestMockBtif",
":TestMockDevice",
":TestMockMainShim",
+ ":TestMockMainShim",
":TestMockMainShimEntry",
":TestMockStackA2dp",
":TestMockStackAcl",
@@ -243,7 +244,6 @@ cc_test {
":TestMockStackGatt",
":TestMockStackHid",
":TestMockStackL2cap",
- ":TestMockStackMetrics",
":TestMockStackPan",
":TestMockStackRfcomm",
":TestMockStackRnr",
@@ -339,10 +339,10 @@ cc_test {
":TestMockBtif",
":TestMockDevice",
":TestMockMainShim",
+ ":TestMockMainShim",
":TestMockMainShimEntry",
":TestMockStackBtm",
":TestMockStackL2cap",
- ":TestMockStackMetrics",
"test/gatt/database_builder_sample_device_test.cc",
"test/gatt/database_builder_test.cc",
"test/gatt/database_test.cc",
diff --git a/system/bta/BUILD.gn b/system/bta/BUILD.gn
index 9c28016617..f621539151 100644
--- a/system/bta/BUILD.gn
+++ b/system/bta/BUILD.gn
@@ -143,7 +143,6 @@ static_library("bta") {
"sys",
"//bt/system/",
"//bt/system/include",
- "//bt/system/linux_include",
"//bt/system/bta",
"//bt/system/bta/aics/include",
"//bt/system/gd",
diff --git a/system/bta/gatt/bta_gattc_utils.cc b/system/bta/gatt/bta_gattc_utils.cc
index 23b150b829..1541f391ca 100644
--- a/system/bta/gatt/bta_gattc_utils.cc
+++ b/system/bta/gatt/bta_gattc_utils.cc
@@ -142,7 +142,7 @@ tBTA_GATTC_CLCB* bta_gattc_find_clcb_by_cif(uint8_t client_if, const RawAddress&
tBTA_GATTC_CLCB* bta_gattc_find_clcb_by_conn_id(tCONN_ID conn_id) {
if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) {
for (auto& p_clcb : bta_gattc_cb.clcb_set) {
- if (p_clcb->in_use && p_clcb->bta_conn_id == conn_id) {
+ if (p_clcb != NULL && p_clcb->in_use && p_clcb->bta_conn_id == conn_id) {
return p_clcb.get();
}
}
diff --git a/system/bta/le_audio/broadcaster/broadcaster_test.cc b/system/bta/le_audio/broadcaster/broadcaster_test.cc
index a211a810ad..16177230d1 100644
--- a/system/bta/le_audio/broadcaster/broadcaster_test.cc
+++ b/system/bta/le_audio/broadcaster/broadcaster_test.cc
@@ -63,6 +63,8 @@ using testing::Test;
using namespace bluetooth::le_audio;
using namespace bluetooth;
+using bluetooth::hci::testing::mock_controller_;
+
using bluetooth::le_audio::DsaMode;
using bluetooth::le_audio::LeAudioCodecConfiguration;
using bluetooth::le_audio::LeAudioSourceAudioHalClient;
@@ -287,8 +289,8 @@ protected:
init_message_loop_thread();
reset_mock_function_count_map();
- bluetooth::hci::testing::mock_controller_ = &mock_controller_;
- ON_CALL(mock_controller_, SupportsBleIsochronousBroadcaster).WillByDefault(Return(true));
+ mock_controller_ = std::make_unique<bluetooth::hci::testing::MockControllerInterface>();
+ ON_CALL(*mock_controller_, SupportsBleIsochronousBroadcaster).WillByDefault(Return(true));
iso_manager_ = bluetooth::hci::IsoManager::GetInstance();
ASSERT_NE(iso_manager_, nullptr);
@@ -366,7 +368,7 @@ protected:
ContentControlIdKeeper::GetInstance()->Stop();
- bluetooth::hci::testing::mock_controller_ = nullptr;
+ bluetooth::hci::testing::mock_controller_.release();
delete mock_audio_source_;
iso_active_callback = nullptr;
delete mock_audio_source_;
@@ -436,7 +438,6 @@ protected:
protected:
MockLeAudioBroadcasterCallbacks mock_broadcaster_callbacks_;
- bluetooth::hci::testing::MockControllerInterface mock_controller_;
bluetooth::hci::IsoManager* iso_manager_;
MockIsoManager* mock_iso_manager_;
bluetooth::hci::iso_manager::BigCallbacks* big_callbacks_ = nullptr;
diff --git a/system/bta/le_audio/codec_manager.cc b/system/bta/le_audio/codec_manager.cc
index 9452218c5d..104d397833 100644
--- a/system/bta/le_audio/codec_manager.cc
+++ b/system/bta/le_audio/codec_manager.cc
@@ -733,11 +733,11 @@ public:
bool AppendStreamMapExtension(const std::vector<struct types::cis>& cises,
const stream_parameters& stream_params, uint8_t direction) {
- // In the legacy mode we are already done
- if (!IsUsingCodecExtensibility()) {
- log::verbose("Codec Extensibility is disabled");
- return true;
- }
+ /* Without the codec extensibility enabled, we still need the BT stack structure to
+ * have the valid extended codec configuration entries, as these are used for codec type
+ * matching. The extended data fields of the AIDL API data structures are filed
+ * right before the AIDL call, only if the codec extensibility is enabled
+ */
const std::string tag =
types::BidirectionalPair<std::string>({.sink = "Sink", .source = "Source"})
diff --git a/system/bta/le_audio/codec_manager_test.cc b/system/bta/le_audio/codec_manager_test.cc
index b8f79a609b..c69464b72e 100644
--- a/system/bta/le_audio/codec_manager_test.cc
+++ b/system/bta/le_audio/codec_manager_test.cc
@@ -300,10 +300,12 @@ public:
bluetooth::legacy::hci::testing::SetMock(legacy_hci_mock_);
- ON_CALL(controller_interface, SupportsBleIsochronousBroadcaster).WillByDefault(Return(true));
- ON_CALL(controller_interface, IsSupported(OpCode::CONFIGURE_DATA_PATH))
+ bluetooth::hci::testing::mock_controller_ =
+ std::make_unique<NiceMock<bluetooth::hci::testing::MockControllerInterface>>();
+ ON_CALL(*bluetooth::hci::testing::mock_controller_, SupportsBleIsochronousBroadcaster)
+ .WillByDefault(Return(true));
+ ON_CALL(*bluetooth::hci::testing::mock_controller_, IsSupported(OpCode::CONFIGURE_DATA_PATH))
.WillByDefault(Return(true));
- bluetooth::hci::testing::mock_controller_ = &controller_interface;
codec_manager = CodecManager::GetInstance();
@@ -311,9 +313,11 @@ public:
RegisterSinkHalClientMock();
}
- virtual void TearDown() override { codec_manager->Stop(); }
+ virtual void TearDown() override {
+ codec_manager->Stop();
+ bluetooth::hci::testing::mock_controller_.release();
+ }
- NiceMock<bluetooth::hci::testing::MockControllerInterface> controller_interface;
CodecManager* codec_manager;
bluetooth::legacy::hci::testing::MockInterface legacy_hci_mock_;
@@ -559,15 +563,16 @@ TEST_F(CodecManagerTestAdsp, testStreamConfigurationMono) {
};
// Stream parameters
+ auto stream_map_entry_mono_bidir =
+ stream_map_info(97, codec_spec_conf::kLeAudioLocationMonoAudio, true);
+ stream_map_entry_mono_bidir.codec_config.id = kLeAudioCodecIdLc3;
types::BidirectionalPair<stream_parameters> stream_params{
.sink =
{
.audio_channel_allocation = codec_spec_conf::kLeAudioLocationMonoAudio,
.stream_config =
{
- .stream_map = {stream_map_info(
- 97, codec_spec_conf::kLeAudioLocationMonoAudio,
- true)},
+ .stream_map = {stream_map_entry_mono_bidir},
.bits_per_sample = 16,
.sampling_frequency_hz = 16000,
.frame_duration_us = 10000,
@@ -583,9 +588,7 @@ TEST_F(CodecManagerTestAdsp, testStreamConfigurationMono) {
.audio_channel_allocation = codec_spec_conf::kLeAudioLocationMonoAudio,
.stream_config =
{
- .stream_map = {stream_map_info(
- 97, codec_spec_conf::kLeAudioLocationMonoAudio,
- true)},
+ .stream_map = {stream_map_entry_mono_bidir},
.bits_per_sample = 16,
.sampling_frequency_hz = 16000,
.frame_duration_us = 10000,
@@ -628,6 +631,7 @@ TEST_F(CodecManagerTestAdsp, testStreamConfigurationMono) {
ASSERT_EQ(codec_spec_conf::kLeAudioLocationMonoAudio, info.audio_channel_allocation);
// The connected should be active
ASSERT_TRUE(info.is_stream_active);
+ ASSERT_EQ(info.codec_config.id.coding_format, kLeAudioCodecIdLc3.coding_format);
} else {
ASSERT_EQ(97, info.stream_handle);
diff --git a/system/bta/le_audio/devices_test.cc b/system/bta/le_audio/devices_test.cc
index adc90e5213..cd711065c4 100644
--- a/system/bta/le_audio/devices_test.cc
+++ b/system/bta/le_audio/devices_test.cc
@@ -514,7 +514,9 @@ protected:
desired_group_size_ = -1;
bluetooth::manager::SetMockBtmInterface(&btm_interface_);
- bluetooth::hci::testing::mock_controller_ = &controller_interface_;
+
+ bluetooth::hci::testing::mock_controller_ =
+ std::make_unique<NiceMock<bluetooth::hci::testing::MockControllerInterface>>();
auto codec_location = ::bluetooth::le_audio::types::CodecLocation::HOST;
bluetooth::le_audio::AudioSetConfigurationProvider::Initialize(codec_location);
@@ -740,6 +742,8 @@ protected:
if (codec_manager_) {
codec_manager_->Stop();
}
+
+ bluetooth::hci::testing::mock_controller_.reset();
}
LeAudioDevice* AddTestDevice(int snk_ase_num, int src_ase_num, int snk_ase_num_cached = 0,
@@ -1417,7 +1421,6 @@ protected:
LeAudioDeviceGroup* group_ = nullptr;
bluetooth::manager::MockBtmInterface btm_interface_;
MockCsisClient mock_csis_client_module_;
- NiceMock<bluetooth::hci::testing::MockControllerInterface> controller_interface_;
bluetooth::le_audio::CodecManager* codec_manager_;
MockCodecManager* mock_codec_manager_;
diff --git a/system/bta/le_audio/le_audio_client_test.cc b/system/bta/le_audio/le_audio_client_test.cc
index a3c52dc9e6..02104518d2 100644
--- a/system/bta/le_audio/le_audio_client_test.cc
+++ b/system/bta/le_audio/le_audio_client_test.cc
@@ -1477,11 +1477,13 @@ protected:
init_message_loop_thread();
reset_mock_function_count_map();
- ON_CALL(controller_, SupportsBleConnectedIsochronousStreamCentral).WillByDefault(Return(true));
- ON_CALL(controller_, SupportsBleConnectedIsochronousStreamPeripheral)
+ hci::testing::mock_controller_ =
+ std::make_unique<NiceMock<bluetooth::hci::testing::MockControllerInterface>>();
+ ON_CALL(*hci::testing::mock_controller_, SupportsBleConnectedIsochronousStreamCentral)
.WillByDefault(Return(true));
- ON_CALL(controller_, SupportsBle2mPhy).WillByDefault(Return(true));
- bluetooth::hci::testing::mock_controller_ = &controller_;
+ ON_CALL(*hci::testing::mock_controller_, SupportsBleConnectedIsochronousStreamPeripheral)
+ .WillByDefault(Return(true));
+ ON_CALL(*hci::testing::mock_controller_, SupportsBle2mPhy).WillByDefault(Return(true));
bluetooth::manager::SetMockBtmInterface(&mock_btm_interface_);
gatt::SetMockBtaGattInterface(&mock_gatt_interface_);
gatt::SetMockBtaGattQueue(&mock_gatt_queue_);
@@ -1595,7 +1597,7 @@ protected:
}
iso_manager_->Stop();
- bluetooth::hci::testing::mock_controller_ = nullptr;
+ hci::testing::mock_controller_.reset();
}
protected:
@@ -2761,7 +2763,6 @@ protected:
/* Audio track metadata */
char* test_tags_ptr_ = nullptr;
- NiceMock<bluetooth::hci::testing::MockControllerInterface> controller_;
};
class UnicastTest : public UnicastTestNoInit {
diff --git a/system/bta/le_audio/state_machine_test.cc b/system/bta/le_audio/state_machine_test.cc
index d17bfda188..e0860515fb 100644
--- a/system/bta/le_audio/state_machine_test.cc
+++ b/system/bta/le_audio/state_machine_test.cc
@@ -261,7 +261,9 @@ protected:
bluetooth::manager::SetMockBtmInterface(&btm_interface);
gatt::SetMockBtaGattInterface(&gatt_interface);
gatt::SetMockBtaGattQueue(&gatt_queue);
- bluetooth::hci::testing::mock_controller_ = &controller_;
+
+ bluetooth::hci::testing::mock_controller_ =
+ std::make_unique<bluetooth::hci::testing::MockControllerInterface>();
overwrite_cis_status_idx_ = 0;
use_cis_retry_cnt_ = false;
@@ -649,7 +651,7 @@ protected:
cached_remote_qos_configuration_for_ase_.clear();
LeAudioGroupStateMachine::Cleanup();
::bluetooth::le_audio::AudioSetConfigurationProvider::Cleanup();
- bluetooth::hci::testing::mock_controller_ = nullptr;
+ bluetooth::hci::testing::mock_controller_.release();
}
std::shared_ptr<LeAudioDevice> PrepareConnectedDevice(uint8_t id,
@@ -1714,7 +1716,6 @@ protected:
std::vector<RawAddress> addresses_;
std::map<uint8_t, std::unique_ptr<LeAudioDeviceGroup>> le_audio_device_groups_;
bool group_create_command_disallowed_ = false;
- bluetooth::hci::testing::MockControllerInterface controller_;
};
class StateMachineTest : public StateMachineTestBase {
diff --git a/system/bta/test/bta_ag_sco_test.cc b/system/bta/test/bta_ag_sco_test.cc
index 16caac7665..a90198c54a 100644
--- a/system/bta/test/bta_ag_sco_test.cc
+++ b/system/bta/test/bta_ag_sco_test.cc
@@ -43,14 +43,14 @@ protected:
this->codec = codec;
return enh_esco_params_t{};
};
- bluetooth::hci::testing::mock_controller_ = &controller_;
+ bluetooth::hci::testing::mock_controller_ =
+ std::make_unique<bluetooth::hci::testing::MockControllerInterface>();
}
void TearDown() override {
test::mock::device_esco_parameters::esco_parameters_for_codec = {};
- bluetooth::hci::testing::mock_controller_ = nullptr;
+ bluetooth::hci::testing::mock_controller_.reset();
}
esco_codec_t codec;
- bluetooth::hci::testing::MockControllerInterface controller_;
};
TEST_P(BtaAgScoParameterSelectionTest, create_sco_cvsd) {
diff --git a/system/bta/test/bta_ag_test.cc b/system/bta/test/bta_ag_test.cc
index 5fa3884669..2114f7e773 100644
--- a/system/bta/test/bta_ag_test.cc
+++ b/system/bta/test/bta_ag_test.cc
@@ -65,7 +65,8 @@ protected:
void SetUp() override {
reset_mock_function_count_map();
fake_osi_ = std::make_unique<test::fake::FakeOsi>();
- bluetooth::hci::testing::mock_controller_ = &controller_;
+ bluetooth::hci::testing::mock_controller_ =
+ std::make_unique<bluetooth::hci::testing::MockControllerInterface>();
main_thread_start_up();
post_on_bt_main([]() { log::info("Main thread started up"); });
@@ -85,7 +86,7 @@ protected:
bta_sys_deregister(BTA_ID_AG);
post_on_bt_main([]() { log::info("Main thread shutting down"); });
main_thread_shut_down();
- bluetooth::hci::testing::mock_controller_ = nullptr;
+ bluetooth::hci::testing::mock_controller_.reset();
}
std::unique_ptr<test::fake::FakeOsi> fake_osi_;
@@ -93,7 +94,6 @@ protected:
uint32_t tmp_num = 0xFFFF;
RawAddress addr;
esco_codec_t codec;
- bluetooth::hci::testing::MockControllerInterface controller_;
};
class BtaAgSwbTest : public BtaAgTest {
diff --git a/system/bta/test/bta_dm_test.cc b/system/bta/test/bta_dm_test.cc
index 90d41d5e6f..b49008b739 100644
--- a/system/bta/test/bta_dm_test.cc
+++ b/system/bta/test/bta_dm_test.cc
@@ -65,10 +65,10 @@ class BtaDmTest : public BtaWithContextTest {
protected:
void SetUp() override {
BtaWithContextTest::SetUp();
- ON_CALL(controller_, LeRand).WillByDefault([](bluetooth::hci::LeRandCallback cb) {
- cb(0x1234);
- });
- bluetooth::hci::testing::mock_controller_ = &controller_;
+ bluetooth::hci::testing::mock_controller_ =
+ std::make_unique<bluetooth::hci::testing::MockControllerInterface>();
+ ON_CALL(*bluetooth::hci::testing::mock_controller_, LeRand)
+ .WillByDefault([](bluetooth::hci::LeRandCallback cb) { cb(0x1234); });
BTA_dm_init();
bluetooth::legacy::testing::bta_dm_init_cb();
@@ -82,9 +82,8 @@ protected:
void TearDown() override {
bluetooth::legacy::testing::bta_dm_deinit_cb();
BtaWithContextTest::TearDown();
- bluetooth::hci::testing::mock_controller_ = nullptr;
+ bluetooth::hci::testing::mock_controller_.reset();
}
- bluetooth::hci::testing::MockControllerInterface controller_;
};
class BtaDmCustomAlarmTest : public BtaDmTest {
diff --git a/system/bta/test/bta_sdp_test.cc b/system/bta/test/bta_sdp_test.cc
index 06e8ff86aa..77f1762cc0 100644
--- a/system/bta/test/bta_sdp_test.cc
+++ b/system/bta/test/bta_sdp_test.cc
@@ -30,17 +30,16 @@ class BtaSdpTest : public BtaWithHwOnTest {
protected:
void SetUp() override {
BtaWithHwOnTest::SetUp();
- ON_CALL(controller_, LeRand).WillByDefault([](bluetooth::hci::LeRandCallback cb) {
- cb(0x1234);
- });
- bluetooth::hci::testing::mock_controller_ = &controller_;
+ bluetooth::hci::testing::mock_controller_ =
+ std::make_unique<bluetooth::hci::testing::MockControllerInterface>();
+ ON_CALL(*bluetooth::hci::testing::mock_controller_, LeRand)
+ .WillByDefault([](bluetooth::hci::LeRandCallback cb) { cb(0x1234); });
}
void TearDown() override {
BtaWithHwOnTest::TearDown();
- bluetooth::hci::testing::mock_controller_ = nullptr;
+ bluetooth::hci::testing::mock_controller_.reset();
}
- bluetooth::hci::testing::MockControllerInterface controller_;
};
class BtaSdpRegisteredTest : public BtaSdpTest {
diff --git a/system/bta/test/bta_test_fixtures.h b/system/bta/test/bta_test_fixtures.h
index c259d0b916..e41e64d496 100644
--- a/system/bta/test/bta_test_fixtures.h
+++ b/system/bta/test/bta_test_fixtures.h
@@ -60,7 +60,8 @@ protected:
ASSERT_NE(get_btm_client_interface().lifecycle.btm_init, nullptr);
ASSERT_NE(get_btm_client_interface().lifecycle.btm_free, nullptr);
- bluetooth::hci::testing::mock_controller_ = &mock_controller_;
+ bluetooth::hci::testing::mock_controller_ =
+ std::make_unique<bluetooth::hci::testing::MockControllerInterface>();
bluetooth::testing::stack::rnr::set_interface(&mock_stack_rnr_interface_);
test::mock::stack_gatt_api::GATT_Register.body =
@@ -85,12 +86,11 @@ protected:
mock_btm_client_interface.eir.BTM_WriteEIR = {};
bluetooth::testing::stack::rnr::reset_interface();
- bluetooth::hci::testing::mock_controller_ = nullptr;
+ bluetooth::hci::testing::mock_controller_.reset();
BtaWithFakesTest::TearDown();
}
- bluetooth::hci::testing::MockControllerInterface mock_controller_;
bluetooth::testing::stack::rnr::Mock mock_stack_rnr_interface_;
};
diff --git a/system/btif/Android.bp b/system/btif/Android.bp
index 0eb097dca7..82544f36ba 100644
--- a/system/btif/Android.bp
+++ b/system/btif/Android.bp
@@ -122,7 +122,6 @@ cc_library_static {
"src/btif_keystore.cc",
"src/btif_le_audio.cc",
"src/btif_le_audio_broadcaster.cc",
- "src/btif_metrics_logging.cc",
"src/btif_pan.cc",
"src/btif_profile_queue.cc",
"src/btif_profile_queue.cc",
diff --git a/system/btif/BUILD.gn b/system/btif/BUILD.gn
index ea6a0f6fbc..9def60989b 100644
--- a/system/btif/BUILD.gn
+++ b/system/btif/BUILD.gn
@@ -64,7 +64,6 @@ static_library("btif") {
"src/btif_jni_task.cc",
"src/btif_keystore.cc",
"src/btif_le_audio.cc",
- "src/btif_metrics_logging.cc",
"src/btif_pan.cc",
"src/btif_profile_queue.cc",
"src/btif_profile_storage.cc",
diff --git a/system/btif/include/btif_metrics_logging.h b/system/btif/include/btif_metrics_logging.h
deleted file mode 100644
index d68eddce5e..0000000000
--- a/system/btif/include/btif_metrics_logging.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright 2021 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.
- */
-
-#pragma once
-
-#include <frameworks/proto_logging/stats/enums/bluetooth/enums.pb.h>
-#include <frameworks/proto_logging/stats/enums/bluetooth/hci/enums.pb.h>
-
-#include "main/shim/metric_id_api.h"
-#include "types/raw_address.h"
-
-void log_a2dp_audio_underrun_event(const RawAddress& address, uint64_t encoding_interval_millis,
- int num_missing_pcm_bytes);
-
-void log_a2dp_audio_overrun_event(const RawAddress& address, uint64_t encoding_interval_millis,
- int num_dropped_buffers, int num_dropped_encoded_frames,
- int num_dropped_encoded_bytes);
-
-void log_a2dp_playback_event(const RawAddress& address, int playback_state, int audio_coding_mode);
-
-void log_a2dp_session_metrics_event(const RawAddress& address, int64_t audio_duration_ms,
- int media_timer_min_ms, int media_timer_max_ms,
- int media_timer_avg_ms, int total_scheduling_count,
- int buffer_overruns_max_count, int buffer_overruns_total,
- float buffer_underruns_average, int buffer_underruns_count,
- int64_t codec_index, bool is_a2dp_offload);
-
-void log_read_rssi_result(const RawAddress& address, uint16_t handle, uint32_t cmd_status,
- int8_t rssi);
-
-void log_read_failed_contact_counter_result(const RawAddress& address, uint16_t handle,
- uint32_t cmd_status, int32_t failed_contact_counter);
-
-void log_read_tx_power_level_result(const RawAddress& address, uint16_t handle, uint32_t cmd_status,
- int32_t transmit_power_level);
-
-void log_counter_metrics_btif(android::bluetooth::CodePathCounterKeyEnum key, int64_t value);
-
-void log_socket_connection_state(const RawAddress& address, int port, int type,
- android::bluetooth::SocketConnectionstateEnum connection_state,
- int64_t tx_bytes, int64_t rx_bytes, int uid, int server_port,
- android::bluetooth::SocketRoleEnum socket_role);
-
-bool init_metric_id_allocator(const std::unordered_map<RawAddress, int>& paired_device_map,
- bluetooth::shim::CallbackLegacy save_id_callback,
- bluetooth::shim::CallbackLegacy forget_device_callback);
-
-bool close_metric_id_allocator();
-
-int allocate_metric_id_from_metric_id_allocator(const RawAddress&);
-
-int save_metric_id_from_metric_id_allocator(const RawAddress&);
-
-void forget_device_from_metric_id_allocator(const RawAddress&);
-
-bool is_valid_id_from_metric_id_allocator(const int id);
diff --git a/system/btif/include/btif_sock_logging.h b/system/btif/include/btif_sock_logging.h
index 7cd30f6396..38dfe3e302 100644
--- a/system/btif/include/btif_sock_logging.h
+++ b/system/btif/include/btif_sock_logging.h
@@ -16,9 +16,11 @@
#pragma once
+#include "hardware/bt_sock.h"
#include "types/raw_address.h"
void btif_sock_connection_logger(const RawAddress& address, int port, int type, int state, int role,
int uid, int server_port, int64_t tx_bytes, int64_t rx_bytes,
- const char* server_name);
+ const char* server_name, uint64_t connection_start_time_ms,
+ btsock_error_code_t error_code, btsock_data_path_t data_path);
void btif_sock_dump(int fd);
diff --git a/system/btif/src/bluetooth.cc b/system/btif/src/bluetooth.cc
index 5741b05c4f..9badbc9ab6 100644
--- a/system/btif/src/bluetooth.cc
+++ b/system/btif/src/bluetooth.cc
@@ -71,7 +71,6 @@
#include "btif/include/btif_hh.h"
#include "btif/include/btif_keystore.h"
#include "btif/include/btif_le_audio.h"
-#include "btif/include/btif_metrics_logging.h"
#include "btif/include/btif_pan.h"
#include "btif/include/btif_profile_storage.h"
#include "btif/include/btif_rc.h"
@@ -99,6 +98,7 @@
#include "hardware/bt_vc.h"
#include "internal_include/bt_target.h"
#include "main/shim/dumpsys.h"
+#include "main/shim/metric_id_api.h"
#include "os/parameter_provider.h"
#include "osi/include/alarm.h"
#include "osi/include/allocator.h"
@@ -1099,7 +1099,7 @@ static std::string obfuscate_address(const RawAddress& address) {
}
static int get_metric_id(const RawAddress& address) {
- return allocate_metric_id_from_metric_id_allocator(address);
+ return bluetooth::shim::AllocateIdFromMetricIdAllocator(address);
}
static int set_dynamic_audio_buffer_size(int codec, int size) {
diff --git a/system/btif/src/btif_a2dp_source.cc b/system/btif/src/btif_a2dp_source.cc
index b8ace80b07..20805a92bd 100644
--- a/system/btif/src/btif_a2dp_source.cc
+++ b/system/btif/src/btif_a2dp_source.cc
@@ -46,13 +46,13 @@
#include "btif_av_co.h"
#include "btif_common.h"
#include "btif_hf.h"
-#include "btif_metrics_logging.h"
#include "btm_iso_api.h"
#include "common/message_loop_thread.h"
#include "common/metrics.h"
#include "common/repeating_timer.h"
#include "common/time_util.h"
#include "hardware/bt_av.h"
+#include "main/shim/metrics_api.h"
#include "osi/include/allocator.h"
#include "osi/include/fixed_queue.h"
#include "osi/include/wakelock.h"
@@ -253,8 +253,6 @@ static bool btif_a2dp_source_startup(void);
static void btif_a2dp_source_startup_delayed(void);
static void btif_a2dp_source_start_session_delayed(const RawAddress& peer_address,
std::promise<void> start_session_promise);
-static void btif_a2dp_source_end_session_delayed(const RawAddress& peer_address);
-static void btif_a2dp_source_shutdown_delayed(std::promise<void>);
static void btif_a2dp_source_audio_tx_start_event(void);
static void btif_a2dp_source_audio_tx_stop_event(void);
static void btif_a2dp_source_audio_tx_flush_event(void);
@@ -262,7 +260,6 @@ static void btif_a2dp_source_audio_tx_flush_event(void);
// The peer address is |peer_addr|.
// This function should be called prior to starting A2DP streaming.
static void btif_a2dp_source_setup_codec(const RawAddress& peer_addr);
-static void btif_a2dp_source_cleanup_codec();
static void btif_a2dp_source_cleanup_codec_delayed();
static void btif_a2dp_source_encoder_user_config_update_event(
const RawAddress& peer_address,
@@ -329,19 +326,13 @@ static void btif_a2dp_source_accumulate_stats(BtifMediaStats* src, BtifMediaStat
src->Reset();
}
-/// Select the thread to run a2dp source actions on (a2dp encoder excluded).
-static bluetooth::common::MessageLoopThread* local_thread() {
- return com::android::bluetooth::flags::a2dp_source_threading_fix() ? get_main_thread()
- : &btif_a2dp_source_thread;
-}
-
bool btif_a2dp_source_init(void) {
log::info("");
// Start A2DP Source media task
btif_a2dp_source_thread.StartUp();
- local_thread()->DoInThread(base::BindOnce(&btif_a2dp_source_init_delayed));
+ do_in_main_thread(base::BindOnce(&btif_a2dp_source_init_delayed));
return true;
}
@@ -422,7 +413,7 @@ static void btif_a2dp_source_init_delayed(void) {
// the provider needs to be initialized earlier in order to ensure
// get_a2dp_configuration and parse_a2dp_configuration can be
// invoked before the stream is started.
- bluetooth::audio::a2dp::init(local_thread(), &a2dp_stream_callbacks,
+ bluetooth::audio::a2dp::init(get_main_thread(), &a2dp_stream_callbacks,
btif_av_is_a2dp_offload_enabled());
}
@@ -439,7 +430,7 @@ static bool btif_a2dp_source_startup(void) {
btif_a2dp_source_cb.tx_audio_queue = fixed_queue_new(SIZE_MAX);
// Schedule the rest of the operations
- local_thread()->DoInThread(base::BindOnce(&btif_a2dp_source_startup_delayed));
+ do_in_main_thread(base::BindOnce(&btif_a2dp_source_startup_delayed));
return true;
}
@@ -451,7 +442,7 @@ static void btif_a2dp_source_startup_delayed() {
log::fatal("unable to enable real time scheduling");
#endif
}
- if (!bluetooth::audio::a2dp::init(local_thread(), &a2dp_stream_callbacks,
+ if (!bluetooth::audio::a2dp::init(get_main_thread(), &a2dp_stream_callbacks,
btif_av_is_a2dp_offload_enabled())) {
log::warn("Failed to setup the bluetooth audio HAL");
}
@@ -464,15 +455,14 @@ bool btif_a2dp_source_start_session(const RawAddress& peer_address,
btif_a2dp_source_audio_tx_flush_req();
- if (local_thread()->DoInThread(base::BindOnce(&btif_a2dp_source_start_session_delayed,
- peer_address, std::move(peer_ready_promise)))) {
- return true;
- } else {
- // cannot set promise but triggers crash
+ if (do_in_main_thread(base::BindOnce(&btif_a2dp_source_start_session_delayed, peer_address,
+ std::move(peer_ready_promise))) != BT_STATUS_SUCCESS) {
log::fatal("peer_address={} state={} fails to context switch", peer_address,
btif_a2dp_source_cb.StateStr());
return false;
}
+
+ return true;
}
static void btif_a2dp_source_start_session_delayed(const RawAddress& peer_address,
@@ -503,7 +493,7 @@ bool btif_a2dp_source_restart_session(const RawAddress& old_peer_address,
log::assert_that(!new_peer_address.IsEmpty(), "assert failed: !new_peer_address.IsEmpty()");
- // Must stop first the audio streaming
+ // Must stop first the audio streaming.
btif_a2dp_source_stop_audio_req();
// If the old active peer was valid, end the old session.
@@ -523,33 +513,30 @@ bool btif_a2dp_source_restart_session(const RawAddress& old_peer_address,
bool btif_a2dp_source_end_session(const RawAddress& peer_address) {
log::info("peer_address={} state={}", peer_address, btif_a2dp_source_cb.StateStr());
- if (com::android::bluetooth::flags::a2dp_source_threading_fix()) {
- btif_a2dp_source_cleanup_codec();
- btif_a2dp_source_end_session_delayed(peer_address);
- } else {
- local_thread()->DoInThread(base::BindOnce(&btif_a2dp_source_end_session_delayed, peer_address));
- btif_a2dp_source_cleanup_codec();
- }
- return true;
-}
-static void btif_a2dp_source_end_session_delayed(const RawAddress& peer_address) {
- log::info("peer_address={} state={}", peer_address, btif_a2dp_source_cb.StateStr());
+ // Must stop first the audio streaming.
+ btif_a2dp_source_stop_audio_req();
+
+ do_in_main_thread(base::BindOnce(&btif_a2dp_source_cleanup_codec_delayed));
+
if ((btif_a2dp_source_cb.State() == BtifA2dpSource::kStateRunning) ||
(btif_a2dp_source_cb.State() == BtifA2dpSource::kStateShuttingDown)) {
btif_av_stream_stop(peer_address);
} else {
log::error("A2DP Source media task is not running");
}
+
if (bluetooth::audio::a2dp::is_hal_enabled()) {
bluetooth::audio::a2dp::end_session();
}
+
+ return true;
}
void btif_a2dp_source_allow_low_latency_audio(bool allowed) {
log::info("allowed={}", allowed);
- local_thread()->DoInThread(
+ do_in_main_thread(
base::BindOnce(bluetooth::audio::a2dp::set_audio_low_latency_mode_allowed, allowed));
}
@@ -561,22 +548,10 @@ void btif_a2dp_source_shutdown(std::promise<void> shutdown_complete_promise) {
return;
}
- /* Make sure no channels are restarted while shutting down */
+ // Make sure no channels are restarted while shutting down.
btif_a2dp_source_cb.SetState(BtifA2dpSource::kStateShuttingDown);
- // TODO(b/374166531) Remove the check for get_main_thread.
- if (local_thread() != get_main_thread()) {
- local_thread()->DoInThread(base::BindOnce(&btif_a2dp_source_shutdown_delayed,
- std::move(shutdown_complete_promise)));
- } else {
- btif_a2dp_source_shutdown_delayed(std::move(shutdown_complete_promise));
- }
-}
-
-static void btif_a2dp_source_shutdown_delayed(std::promise<void> shutdown_complete_promise) {
- log::info("state={}", btif_a2dp_source_cb.StateStr());
-
- // Stop the timer
+ // Stop the timer.
btif_a2dp_source_cb.media_alarm.CancelAndWait();
wakelock_release();
@@ -676,13 +651,6 @@ static void btif_a2dp_source_setup_codec(const RawAddress& peer_address) {
}
}
-static void btif_a2dp_source_cleanup_codec() {
- log::info("state={}", btif_a2dp_source_cb.StateStr());
- // Must stop media task first before cleaning up the encoder
- btif_a2dp_source_stop_audio_req();
- local_thread()->DoInThread(base::BindOnce(&btif_a2dp_source_cleanup_codec_delayed));
-}
-
static void btif_a2dp_source_cleanup_codec_delayed() {
log::info("state={}", btif_a2dp_source_cb.StateStr());
if (btif_a2dp_source_cb.encoder_interface != nullptr) {
@@ -694,13 +662,13 @@ static void btif_a2dp_source_cleanup_codec_delayed() {
void btif_a2dp_source_start_audio_req(void) {
log::info("state={}", btif_a2dp_source_cb.StateStr());
- local_thread()->DoInThread(base::BindOnce(&btif_a2dp_source_audio_tx_start_event));
+ do_in_main_thread(base::BindOnce(&btif_a2dp_source_audio_tx_start_event));
}
void btif_a2dp_source_stop_audio_req(void) {
log::info("state={}", btif_a2dp_source_cb.StateStr());
- local_thread()->DoInThread(base::BindOnce(&btif_a2dp_source_audio_tx_stop_event));
+ do_in_main_thread(base::BindOnce(&btif_a2dp_source_audio_tx_stop_event));
}
void btif_a2dp_source_encoder_user_config_update_req(
@@ -710,9 +678,9 @@ void btif_a2dp_source_encoder_user_config_update_req(
log::info("peer_address={} state={} {} codec_preference(s)", peer_address,
btif_a2dp_source_cb.StateStr(), codec_user_preferences.size());
- if (!local_thread()->DoInThread(
- base::BindOnce(&btif_a2dp_source_encoder_user_config_update_event, peer_address,
- codec_user_preferences, std::move(peer_ready_promise)))) {
+ if (do_in_main_thread(base::BindOnce(&btif_a2dp_source_encoder_user_config_update_event,
+ peer_address, codec_user_preferences,
+ std::move(peer_ready_promise))) != BT_STATUS_SUCCESS) {
// cannot set promise but triggers crash
log::fatal("peer_address={} state={} fails to context switch", peer_address,
btif_a2dp_source_cb.StateStr());
@@ -755,7 +723,7 @@ static void btif_a2dp_source_encoder_user_config_update_event(
void btif_a2dp_source_feeding_update_req(const btav_a2dp_codec_config_t& codec_audio_config) {
log::info("state={}", btif_a2dp_source_cb.StateStr());
- local_thread()->DoInThread(
+ do_in_main_thread(
base::BindOnce(&btif_a2dp_source_audio_feeding_update_event, codec_audio_config));
}
@@ -963,8 +931,9 @@ static uint32_t btif_a2dp_source_read_callback(uint8_t* p_buf, uint32_t len) {
btif_a2dp_source_cb.stats.media_read_total_underflow_count++;
btif_a2dp_source_cb.stats.media_read_last_underflow_us =
bluetooth::common::time_get_os_boottime_us();
- log_a2dp_audio_underrun_event(btif_av_source_active_peer(),
- btif_a2dp_source_cb.encoder_interval_ms, len - bytes_read);
+ bluetooth::shim::LogMetricA2dpAudioUnderrunEvent(btif_av_source_active_peer(),
+ btif_a2dp_source_cb.encoder_interval_ms,
+ len - bytes_read);
}
return bytes_read;
@@ -1016,9 +985,9 @@ static bool btif_a2dp_source_enqueue_callback(BT_HDR* p_buf, size_t frames_n,
osi_free(p_data);
}
}
- log_a2dp_audio_overrun_event(btif_av_source_active_peer(),
- btif_a2dp_source_cb.encoder_interval_ms, drop_n,
- num_dropped_encoded_frames, num_dropped_encoded_bytes);
+ bluetooth::shim::LogMetricA2dpAudioOverrunEvent(
+ btif_av_source_active_peer(), btif_a2dp_source_cb.encoder_interval_ms, drop_n,
+ num_dropped_encoded_frames, num_dropped_encoded_bytes);
// Request additional debug info if we had to flush buffers
RawAddress peer_bda = btif_av_source_active_peer();
@@ -1069,7 +1038,7 @@ static void btif_a2dp_source_audio_tx_flush_event(void) {
static bool btif_a2dp_source_audio_tx_flush_req(void) {
log::info("state={}", btif_a2dp_source_cb.StateStr());
- local_thread()->DoInThread(base::BindOnce(&btif_a2dp_source_audio_tx_flush_event));
+ do_in_main_thread(base::BindOnce(&btif_a2dp_source_audio_tx_flush_event));
return true;
}
@@ -1308,12 +1277,12 @@ static void btif_a2dp_source_update_metrics(void) {
}
if (metrics.audio_duration_ms != -1) {
- log_a2dp_session_metrics_event(btif_av_source_active_peer(), metrics.audio_duration_ms,
- metrics.media_timer_min_ms, metrics.media_timer_max_ms,
- metrics.media_timer_avg_ms, metrics.total_scheduling_count,
- metrics.buffer_overruns_max_count, metrics.buffer_overruns_total,
- metrics.buffer_underruns_average, metrics.buffer_underruns_count,
- metrics.codec_index, metrics.is_a2dp_offload);
+ bluetooth::shim::LogMetricA2dpSessionMetricsEvent(
+ btif_av_source_active_peer(), metrics.audio_duration_ms, metrics.media_timer_min_ms,
+ metrics.media_timer_max_ms, metrics.media_timer_avg_ms, metrics.total_scheduling_count,
+ metrics.buffer_overruns_max_count, metrics.buffer_overruns_total,
+ metrics.buffer_underruns_average, metrics.buffer_underruns_count, metrics.codec_index,
+ metrics.is_a2dp_offload);
}
}
@@ -1333,8 +1302,9 @@ static void btm_read_rssi_cb(void* data) {
return;
}
- log_read_rssi_result(result->rem_bda, bluetooth::common::kUnknownConnectionHandle,
- result->hci_status, result->rssi);
+ bluetooth::shim::LogMetricReadRssiResult(result->rem_bda,
+ bluetooth::common::kUnknownConnectionHandle,
+ result->hci_status, result->rssi);
log::warn("device: {}, rssi: {}", result->rem_bda, result->rssi);
}
@@ -1350,9 +1320,9 @@ static void btm_read_failed_contact_counter_cb(void* data) {
log::error("unable to read Failed Contact Counter (status {})", result->status);
return;
}
- log_read_failed_contact_counter_result(result->rem_bda,
- bluetooth::common::kUnknownConnectionHandle,
- result->hci_status, result->failed_contact_counter);
+ bluetooth::shim::LogMetricReadFailedContactCounterResult(
+ result->rem_bda, bluetooth::common::kUnknownConnectionHandle, result->hci_status,
+ result->failed_contact_counter);
log::warn("device: {}, Failed Contact Counter: {}", result->rem_bda,
result->failed_contact_counter);
@@ -1369,8 +1339,9 @@ static void btm_read_tx_power_cb(void* data) {
log::error("unable to read Tx Power (status {})", result->status);
return;
}
- log_read_tx_power_level_result(result->rem_bda, bluetooth::common::kUnknownConnectionHandle,
- result->hci_status, result->tx_power);
+ bluetooth::shim::LogMetricReadTxPowerLevelResult(result->rem_bda,
+ bluetooth::common::kUnknownConnectionHandle,
+ result->hci_status, result->tx_power);
log::warn("device: {}, Tx Power: {}", result->rem_bda, result->tx_power);
}
diff --git a/system/btif/src/btif_av.cc b/system/btif/src/btif_av.cc
index e4f784a39c..2ee3be4c88 100644
--- a/system/btif/src/btif_av.cc
+++ b/system/btif/src/btif_av.cc
@@ -52,18 +52,17 @@
#include "btif/include/btif_a2dp_source.h"
#include "btif/include/btif_av_co.h"
#include "btif/include/btif_common.h"
-#include "btif/include/btif_metrics_logging.h"
#include "btif/include/btif_profile_queue.h"
#include "btif/include/btif_rc.h"
#include "btif/include/btif_util.h"
#include "btif/include/stack_manager_t.h"
-#include "btif_metrics_logging.h"
#include "common/state_machine.h"
#include "device/include/device_iot_conf_defs.h"
#include "device/include/device_iot_config.h"
#include "hardware/bluetooth.h"
#include "hardware/bt_av.h"
#include "include/hardware/bt_rc.h"
+#include "main/shim/metrics_api.h"
#include "osi/include/alarm.h"
#include "osi/include/allocator.h"
#include "osi/include/properties.h"
@@ -1985,7 +1984,7 @@ bool BtifAvStateMachine::StateOpening::ProcessEvent(uint32_t event, void* p_data
// incoming/outgoing connect/disconnect requests.
log::warn("Peer {} : event={}: transitioning to Idle due to ACL Disconnect",
peer_.PeerAddress(), BtifAvEvent::EventName(event));
- log_counter_metrics_btif(
+ bluetooth::shim::CountCounterMetrics(
android::bluetooth::CodePathCounterKeyEnum::A2DP_CONNECTION_ACL_DISCONNECTED, 1);
btif_report_connection_state(peer_.PeerAddress(), BTAV_CONNECTION_STATE_DISCONNECTED,
bt_status_t::BT_STATUS_FAIL, BTA_AV_FAIL,
@@ -1998,7 +1997,7 @@ bool BtifAvStateMachine::StateOpening::ProcessEvent(uint32_t event, void* p_data
case BTA_AV_REJECT_EVT:
log::warn("Peer {} : event={} flags={}", peer_.PeerAddress(), BtifAvEvent::EventName(event),
peer_.FlagsToString());
- log_counter_metrics_btif(
+ bluetooth::shim::CountCounterMetrics(
android::bluetooth::CodePathCounterKeyEnum::A2DP_CONNECTION_REJECT_EVT, 1);
btif_report_connection_state(peer_.PeerAddress(), BTAV_CONNECTION_STATE_DISCONNECTED,
bt_status_t::BT_STATUS_AUTH_REJECTED, BTA_AV_FAIL,
@@ -2080,7 +2079,7 @@ bool BtifAvStateMachine::StateOpening::ProcessEvent(uint32_t event, void* p_data
btif_report_connection_state(peer_.PeerAddress(), BTAV_CONNECTION_STATE_CONNECTED,
bt_status_t::BT_STATUS_SUCCESS, BTA_AV_SUCCESS,
peer_.IsSource() ? A2dpType::kSink : A2dpType::kSource);
- log_counter_metrics_btif(
+ bluetooth::shim::CountCounterMetrics(
android::bluetooth::CodePathCounterKeyEnum::A2DP_CONNECTION_SUCCESS, 1);
} else {
if (btif_rc_is_connected_peer(peer_.PeerAddress())) {
@@ -2099,7 +2098,7 @@ bool BtifAvStateMachine::StateOpening::ProcessEvent(uint32_t event, void* p_data
btif_report_connection_state(peer_.PeerAddress(), BTAV_CONNECTION_STATE_DISCONNECTED,
bt_status_t::BT_STATUS_FAIL, status,
peer_.IsSource() ? A2dpType::kSink : A2dpType::kSource);
- log_counter_metrics_btif(
+ bluetooth::shim::CountCounterMetrics(
android::bluetooth::CodePathCounterKeyEnum::A2DP_CONNECTION_FAILURE, 1);
}
@@ -2139,8 +2138,8 @@ bool BtifAvStateMachine::StateOpening::ProcessEvent(uint32_t event, void* p_data
"Peer {} : event={} : device is already connecting, ignore Connect "
"request",
peer_.PeerAddress(), BtifAvEvent::EventName(event));
- log_counter_metrics_btif(android::bluetooth::CodePathCounterKeyEnum::A2DP_ALREADY_CONNECTING,
- 1);
+ bluetooth::shim::CountCounterMetrics(
+ android::bluetooth::CodePathCounterKeyEnum::A2DP_ALREADY_CONNECTING, 1);
btif_queue_advance();
} break;
@@ -2151,15 +2150,15 @@ bool BtifAvStateMachine::StateOpening::ProcessEvent(uint32_t event, void* p_data
"Peer {} : event={} : device is already connecting, ignore incoming "
"request",
peer_.PeerAddress(), BtifAvEvent::EventName(event));
- log_counter_metrics_btif(android::bluetooth::CodePathCounterKeyEnum::A2DP_ALREADY_CONNECTING,
- 1);
+ bluetooth::shim::CountCounterMetrics(
+ android::bluetooth::CodePathCounterKeyEnum::A2DP_ALREADY_CONNECTING, 1);
} break;
case BTIF_AV_OFFLOAD_START_REQ_EVT:
log::error("Peer {} : event={}: stream is not Opened", peer_.PeerAddress(),
BtifAvEvent::EventName(event));
btif_a2dp_on_offload_started(peer_.PeerAddress(), BTA_AV_FAIL);
- log_counter_metrics_btif(
+ bluetooth::shim::CountCounterMetrics(
android::bluetooth::CodePathCounterKeyEnum::A2DP_OFFLOAD_START_REQ_FAILURE, 1);
break;
@@ -2169,8 +2168,8 @@ bool BtifAvStateMachine::StateOpening::ProcessEvent(uint32_t event, void* p_data
bt_status_t::BT_STATUS_FAIL, BTA_AV_FAIL,
peer_.IsSource() ? A2dpType::kSink : A2dpType::kSource);
peer_.StateMachine().TransitionTo(BtifAvStateMachine::kStateIdle);
- log_counter_metrics_btif(android::bluetooth::CodePathCounterKeyEnum::A2DP_CONNECTION_CLOSE,
- 1);
+ bluetooth::shim::CountCounterMetrics(
+ android::bluetooth::CodePathCounterKeyEnum::A2DP_CONNECTION_CLOSE, 1);
DEVICE_IOT_CONFIG_ADDR_INT_ADD_ONE(peer_.PeerAddress(), IOT_CONF_KEY_A2DP_CONN_FAIL_COUNT);
if (peer_.SelfInitiatedConnection()) {
btif_queue_advance();
@@ -2184,7 +2183,7 @@ bool BtifAvStateMachine::StateOpening::ProcessEvent(uint32_t event, void* p_data
peer_.IsSource() ? A2dpType::kSink : A2dpType::kSource);
peer_.StateMachine().TransitionTo(BtifAvStateMachine::kStateIdle);
DEVICE_IOT_CONFIG_ADDR_INT_ADD_ONE(peer_.PeerAddress(), IOT_CONF_KEY_A2DP_CONN_FAIL_COUNT);
- log_counter_metrics_btif(
+ bluetooth::shim::CountCounterMetrics(
android::bluetooth::CodePathCounterKeyEnum::A2DP_CONNECTION_DISCONNECTED, 1);
if (peer_.SelfInitiatedConnection()) {
btif_queue_advance();
@@ -2203,7 +2202,7 @@ bool BtifAvStateMachine::StateOpening::ProcessEvent(uint32_t event, void* p_data
CHECK_RC_EVENT(event, reinterpret_cast<tBTA_AV*>(p_data));
default:
- log_counter_metrics_btif(
+ bluetooth::shim::CountCounterMetrics(
android::bluetooth::CodePathCounterKeyEnum::A2DP_CONNECTION_UNKNOWN_EVENT, 1);
log::warn("Peer {} : Unhandled event={}", peer_.PeerAddress(), BtifAvEvent::EventName(event));
return false;
@@ -2400,12 +2399,10 @@ bool BtifAvStateMachine::StateOpened::ProcessEvent(uint32_t event, void* p_data)
std::promise<void> peer_ready_promise;
std::future<void> peer_ready_future = peer_ready_promise.get_future();
- if (com::android::bluetooth::flags::a2dp_clear_pending_start_on_session_restart()) {
- // The stream may not be restarted without an explicit request from the
- // Bluetooth Audio HAL. Any start request that was pending before the
- // reconfiguration is invalidated when the session is ended.
- peer_.ClearFlags(BtifAvPeer::kFlagPendingStart);
- }
+ // The stream may not be restarted without an explicit request from the
+ // Bluetooth Audio HAL. Any start request that was pending before the
+ // reconfiguration is invalidated when the session is ended.
+ peer_.ClearFlags(BtifAvPeer::kFlagPendingStart);
btif_a2dp_source_start_session(peer_.PeerAddress(), std::move(peer_ready_promise));
}
@@ -2935,7 +2932,7 @@ static void btif_report_audio_state(const RawAddress& peer_address, btav_audio_s
? AudioCodingModeEnum::AUDIO_CODING_MODE_HARDWARE
: AudioCodingModeEnum::AUDIO_CODING_MODE_SOFTWARE;
- log_a2dp_playback_event(peer_address, playback_state, audio_coding_mode);
+ bluetooth::shim::LogMetricA2dpPlaybackEvent(peer_address, playback_state, audio_coding_mode);
}
void btif_av_report_source_codec_state(
diff --git a/system/btif/src/btif_config.cc b/system/btif/src/btif_config.cc
index 2ee8fe494d..9a0e50dea1 100644
--- a/system/btif/src/btif_config.cc
+++ b/system/btif/src/btif_config.cc
@@ -32,9 +32,10 @@
#include <unordered_map>
#include "btif_keystore.h"
-#include "btif_metrics_logging.h"
#include "common/address_obfuscator.h"
#include "main/shim/config.h"
+#include "main/shim/metric_id_api.h"
+#include "main/shim/metrics_api.h"
#include "main/shim/shim.h"
#include "storage/config_keys.h"
#include "types/raw_address.h"
@@ -111,7 +112,7 @@ static void init_metric_id_allocator() {
// there is one metric id under this mac_address
int id = 0;
btif_config_get_int(addr_str, BTIF_STORAGE_KEY_METRICS_ID_KEY, &id);
- if (is_valid_id_from_metric_id_allocator(id)) {
+ if (bluetooth::shim::IsValidIdFromMetricIdAllocator(id)) {
paired_device_map[mac_address] = id;
is_valid_id_found = true;
}
@@ -128,15 +129,15 @@ static void init_metric_id_allocator() {
auto forget_device_callback = [](const RawAddress& address, const int /* id */) {
return btif_config_remove(address.ToString(), BTIF_STORAGE_KEY_METRICS_ID_KEY);
};
- if (!init_metric_id_allocator(paired_device_map, std::move(save_device_callback),
- std::move(forget_device_callback))) {
+ if (!bluetooth::shim::InitMetricIdAllocator(paired_device_map, std::move(save_device_callback),
+ std::move(forget_device_callback))) {
log::fatal("Failed to initialize MetricIdAllocator");
}
// Add device_without_id
for (auto& address : addresses_without_id) {
- allocate_metric_id_from_metric_id_allocator(address);
- save_metric_id_from_metric_id_allocator(address);
+ bluetooth::shim::AllocateIdFromMetricIdAllocator(address);
+ bluetooth::shim::SaveDeviceOnMetricIdAllocator(address);
}
}
@@ -160,7 +161,7 @@ static future_t* clean_up(void) {
"assert failed: bluetooth::shim::is_gd_stack_started_up()");
// GD storage module cleanup by itself
std::unique_lock<std::recursive_mutex> lock(config_lock);
- close_metric_id_allocator();
+ bluetooth::shim::CloseMetricIdAllocator();
return future_new_immediate(FUTURE_SUCCESS);
}
diff --git a/system/btif/src/btif_dm.cc b/system/btif/src/btif_dm.cc
index 96ed5848b1..e10606b9dd 100644
--- a/system/btif/src/btif_dm.cc
+++ b/system/btif/src/btif_dm.cc
@@ -57,7 +57,6 @@
#include "btif_api.h"
#include "btif_bqr.h"
#include "btif_config.h"
-#include "btif_metrics_logging.h"
#include "btif_sdp.h"
#include "btif_storage.h"
#include "btif_util.h"
@@ -72,6 +71,8 @@
#include "main/shim/entry.h"
#include "main/shim/helpers.h"
#include "main/shim/le_advertising_manager.h"
+#include "main/shim/metric_id_api.h"
+#include "main/shim/metrics_api.h"
#include "main_thread.h"
#include "metrics/bluetooth_event.h"
#include "os/system_properties.h"
@@ -582,11 +583,11 @@ static void bond_state_changed(bt_status_t status, const RawAddress& bd_addr,
state, pairing_cb.state, pairing_cb.sdp_attempts);
if (state == BT_BOND_STATE_NONE) {
- forget_device_from_metric_id_allocator(bd_addr);
+ bluetooth::shim::ForgetDeviceFromMetricIdAllocator(bd_addr);
btif_config_remove_device(bd_addr.ToString());
} else if (state == BT_BOND_STATE_BONDED) {
- allocate_metric_id_from_metric_id_allocator(bd_addr);
- if (!save_metric_id_from_metric_id_allocator(bd_addr)) {
+ bluetooth::shim::AllocateIdFromMetricIdAllocator(bd_addr);
+ if (!bluetooth::shim::SaveDeviceOnMetricIdAllocator(bd_addr)) {
log::error("Fail to save metric id for device:{}", bd_addr);
}
}
@@ -1485,7 +1486,7 @@ static void btif_dm_search_devices_evt(tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH*
auto triple = eir_uuids_cache.try_emplace(bdaddr, std::set<Uuid>{});
uuid_iter = std::get<0>(triple);
}
- log::info("EIR UUIDs for {}:", bdaddr);
+ log::info("EIR UUIDs for {}", bdaddr);
for (int i = 0; i < num_uuids; ++i) {
Uuid uuid = Uuid::From16Bit(p_uuid16[i]);
log::info("{}", uuid.ToString());
@@ -1608,7 +1609,7 @@ static void btif_on_service_discovery_results(RawAddress bd_addr,
if (results_for_bonding_device) {
// success for SDP
bluetooth::metrics::LogSDPComplete(bd_addr, tBTA_STATUS::BTA_SUCCESS);
- log::info("SDP finished for {}:", bd_addr);
+ log::info("SDP finished for {}", bd_addr);
pairing_cb.sdp_over_classic = btif_dm_pairing_cb_t::ServiceDiscoveryState::FINISHED;
}
@@ -1619,7 +1620,7 @@ static void btif_on_service_discovery_results(RawAddress bd_addr,
bt_property_t& le_prop = uuid_props[1];
if ((result == BTA_SUCCESS) && !uuids_param.empty()) {
- log::info("New UUIDs for {}:", bd_addr);
+ log::info("New UUIDs for {}", bd_addr);
for (const auto& uuid : uuids_param) {
if (btif_should_ignore_uuid(uuid)) {
continue;
@@ -1757,7 +1758,7 @@ static void btif_on_gatt_results(RawAddress bd_addr, std::vector<bluetooth::Uuid
bool lea_supported = is_le_audio_capable_during_service_discovery(bd_addr);
if (is_transport_le) {
- log::info("New GATT over LE UUIDs for {}:", bd_addr);
+ log::info("New GATT over LE UUIDs for {}", bd_addr);
BTM_LogHistory(kBtmLogTag, bd_addr, "Discovered GATT services using LE transport");
if (btif_is_gatt_service_discovery_post_pairing(bd_addr)) {
pairing_cb.gatt_over_le = btif_dm_pairing_cb_t::ServiceDiscoveryState::FINISHED;
@@ -1785,7 +1786,7 @@ static void btif_on_gatt_results(RawAddress bd_addr, std::vector<bluetooth::Uuid
}
}
} else {
- log::debug("New GATT over SDP UUIDs for {}:", bd_addr);
+ log::debug("New GATT over SDP UUIDs for {}", bd_addr);
BTM_LogHistory(kBtmLogTag, bd_addr, "Discovered GATT services using SDP transport");
}
diff --git a/system/btif/src/btif_hf.cc b/system/btif/src/btif_hf.cc
index 33fb900e07..178a1672e6 100644
--- a/system/btif/src/btif_hf.cc
+++ b/system/btif/src/btif_hf.cc
@@ -51,7 +51,6 @@
#include "bta/include/utl.h"
#include "bta_ag_swb_aptx.h"
#include "btif/include/btif_common.h"
-#include "btif/include/btif_metrics_logging.h"
#include "btif/include/btif_profile_queue.h"
#include "btif/include/btif_util.h"
#include "btm_api_types.h"
@@ -390,7 +389,7 @@ static void btif_hf_upstreams_evt(uint16_t event, char* p_param) {
p_data->open.status, btif_hf_cb[idx].connected_bda, p_data->open.bd_addr);
bt_hf_callbacks->ConnectionStateCallback(BTHF_CONNECTION_STATE_DISCONNECTED,
&(p_data->open.bd_addr));
- log_counter_metrics_btif(
+ bluetooth::shim::CountCounterMetrics(
android::bluetooth::CodePathCounterKeyEnum::HFP_COLLISON_AT_AG_OPEN, 1);
}
break;
@@ -412,7 +411,7 @@ static void btif_hf_upstreams_evt(uint16_t event, char* p_param) {
btif_hf_cb[idx].connected_bda, p_data->open.bd_addr);
bt_hf_callbacks->ConnectionStateCallback(BTHF_CONNECTION_STATE_DISCONNECTED,
&(btif_hf_cb[idx].connected_bda));
- log_counter_metrics_btif(
+ bluetooth::shim::CountCounterMetrics(
android::bluetooth::CodePathCounterKeyEnum::HFP_COLLISON_AT_CONNECTING, 1);
reset_control_block(&btif_hf_cb[idx]);
btif_queue_advance();
@@ -472,7 +471,7 @@ static void btif_hf_upstreams_evt(uint16_t event, char* p_param) {
bt_hf_callbacks->ConnectionStateCallback(btif_hf_cb[idx].state, &connected_bda);
}
- log_counter_metrics_btif(
+ bluetooth::shim::CountCounterMetrics(
android::bluetooth::CodePathCounterKeyEnum::HFP_SELF_INITIATED_AG_FAILED, 1);
btif_queue_advance();
if (btm_sec_is_a_bonded_dev(connected_bda)) {
@@ -496,8 +495,8 @@ static void btif_hf_upstreams_evt(uint16_t event, char* p_param) {
bt_hf_callbacks->ConnectionStateCallback(btif_hf_cb[idx].state, &connected_bda);
if (failed_to_setup_slc) {
log::error("failed to setup SLC for {}", connected_bda);
- log_counter_metrics_btif(android::bluetooth::CodePathCounterKeyEnum::HFP_SLC_SETUP_FAILED,
- 1);
+ bluetooth::shim::CountCounterMetrics(
+ android::bluetooth::CodePathCounterKeyEnum::HFP_SLC_SETUP_FAILED, 1);
btif_queue_advance();
LogMetricHfpSlcFail(ToGdAddress(p_data->open.bd_addr));
DEVICE_IOT_CONFIG_ADDR_INT_ADD_ONE(btif_hf_cb[idx].connected_bda,
@@ -881,7 +880,7 @@ public:
bt_status_t DisconnectAudio(RawAddress* bd_addr) override;
bt_status_t isNoiseReductionSupported(RawAddress* bd_addr) override;
bt_status_t isVoiceRecognitionSupported(RawAddress* bd_addr) override;
- bt_status_t StartVoiceRecognition(RawAddress* bd_addr) override;
+ bt_status_t StartVoiceRecognition(RawAddress* bd_addr, bool sendResult) override;
bt_status_t StopVoiceRecognition(RawAddress* bd_addr) override;
bt_status_t VolumeControl(bthf_volume_type_t type, int volume, RawAddress* bd_addr) override;
bt_status_t DeviceStatusNotification(bthf_network_state_t ntk_state, bthf_service_type_t svc_type,
@@ -1024,7 +1023,7 @@ bt_status_t HeadsetInterface::isVoiceRecognitionSupported(RawAddress* bd_addr) {
return BT_STATUS_SUCCESS;
}
-bt_status_t HeadsetInterface::StartVoiceRecognition(RawAddress* bd_addr) {
+bt_status_t HeadsetInterface::StartVoiceRecognition(RawAddress* bd_addr, bool sendResult) {
CHECK_BTHF_INIT();
int idx = btif_hf_idx_by_bdaddr(bd_addr);
if ((idx < 0) || (idx >= BTA_AG_MAX_NUM_CLIENTS)) {
@@ -1040,9 +1039,11 @@ bt_status_t HeadsetInterface::StartVoiceRecognition(RawAddress* bd_addr) {
return BT_STATUS_UNSUPPORTED;
}
btif_hf_cb[idx].is_during_voice_recognition = true;
- tBTA_AG_RES_DATA ag_res = {};
- ag_res.state = true;
- BTA_AgResult(btif_hf_cb[idx].handle, BTA_AG_BVRA_RES, ag_res);
+ if (sendResult) {
+ tBTA_AG_RES_DATA ag_res = {};
+ ag_res.state = true;
+ BTA_AgResult(btif_hf_cb[idx].handle, BTA_AG_BVRA_RES, ag_res);
+ }
return BT_STATUS_SUCCESS;
}
diff --git a/system/btif/src/btif_hh.cc b/system/btif/src/btif_hh.cc
index 7288abe98c..36ad3d148e 100644
--- a/system/btif/src/btif_hh.cc
+++ b/system/btif/src/btif_hh.cc
@@ -48,7 +48,6 @@
#include "btif/include/btif_common.h"
#include "btif/include/btif_dm.h"
#include "btif/include/btif_hd.h"
-#include "btif/include/btif_metrics_logging.h"
#include "btif/include/btif_profile_storage.h"
#include "btif/include/btif_storage.h"
#include "btif/include/btif_util.h"
@@ -56,6 +55,7 @@
#include "include/hardware/bt_hh.h"
#include "internal_include/bt_target.h"
#include "main/shim/dumpsys.h"
+#include "main/shim/metrics_api.h"
#include "osi/include/alarm.h"
#include "osi/include/allocator.h"
#include "stack/include/bt_hdr.h"
@@ -468,7 +468,7 @@ static void btif_hh_incoming_connection_timeout(void* data) {
handle);
}
log::warn("Reject unexpected incoming HID Connection, device: {}", conn.link_spec);
- log_counter_metrics_btif(
+ bluetooth::shim::CountCounterMetrics(
android::bluetooth::CodePathCounterKeyEnum::HIDH_COUNT_INCOMING_CONNECTION_REJECTED, 1);
btif_hh_device_t* p_dev = btif_hh_find_dev_by_link_spec(conn.link_spec);
@@ -529,7 +529,7 @@ static bool hh_add_device(const tAclLinkSpec& link_spec, tBTA_HH_ATTR_MASK attr_
}
log::error("Out of space to add device");
- log_counter_metrics_btif(
+ bluetooth::shim::CountCounterMetrics(
android::bluetooth::CodePathCounterKeyEnum::HIDH_COUNT_MAX_ADDED_DEVICE_LIMIT_REACHED, 1);
return false;
}
@@ -633,7 +633,7 @@ static void hh_open_handler(tBTA_HH_CONN& conn) {
log::warn("Reject Incoming HID Connection, device: {}, state: {}", conn.link_spec,
bthh_connection_state_text(dev_status));
- log_counter_metrics_btif(
+ bluetooth::shim::CountCounterMetrics(
android::bluetooth::CodePathCounterKeyEnum::HIDH_COUNT_INCOMING_CONNECTION_REJECTED, 1);
if (p_dev != nullptr) {
@@ -910,9 +910,10 @@ static void hh_vc_unplug_handler(tBTA_HH_CBDATA& dev_status) {
BTHH_STATE_UPDATE(p_dev->link_spec, p_dev->dev_status);
if (!p_dev->local_vup) {
- log_counter_metrics_btif(android::bluetooth::CodePathCounterKeyEnum::
- HIDH_COUNT_VIRTUAL_UNPLUG_REQUESTED_BY_REMOTE_DEVICE,
- 1);
+ bluetooth::shim::CountCounterMetrics(
+ android::bluetooth::CodePathCounterKeyEnum::
+ HIDH_COUNT_VIRTUAL_UNPLUG_REQUESTED_BY_REMOTE_DEVICE,
+ 1);
}
// Remove the HID device
@@ -1193,9 +1194,10 @@ bt_status_t btif_hh_connect(const tAclLinkSpec& link_spec) {
if (!p_dev && btif_hh_cb.device_num >= BTIF_HH_MAX_HID) {
// No space for more HID device now.
log::warn("Error, exceeded the maximum supported HID device number {}", BTIF_HH_MAX_HID);
- log_counter_metrics_btif(android::bluetooth::CodePathCounterKeyEnum::
- HIDH_COUNT_CONNECT_REQ_WHEN_MAX_DEVICE_LIMIT_REACHED,
- 1);
+ bluetooth::shim::CountCounterMetrics(
+ android::bluetooth::CodePathCounterKeyEnum::
+ HIDH_COUNT_CONNECT_REQ_WHEN_MAX_DEVICE_LIMIT_REACHED,
+ 1);
return BT_STATUS_NOMEM;
}
@@ -2030,7 +2032,7 @@ static bt_status_t get_report(RawAddress* bd_addr, tBLE_ADDR_TYPE addr_type,
return BT_STATUS_DEVICE_NOT_FOUND;
} else if (((int)reportType) <= BTA_HH_RPTT_RESRV || ((int)reportType) > BTA_HH_RPTT_FEATURE) {
log::error("report type={} not supported", reportType);
- log_counter_metrics_btif(
+ bluetooth::shim::CountCounterMetrics(
android::bluetooth::CodePathCounterKeyEnum::HIDH_COUNT_WRONG_REPORT_TYPE, 1);
return BT_STATUS_UNSUPPORTED;
} else {
@@ -2102,7 +2104,7 @@ static bt_status_t set_report(RawAddress* bd_addr, tBLE_ADDR_TYPE addr_type,
return BT_STATUS_DEVICE_NOT_FOUND;
} else if (((int)reportType) <= BTA_HH_RPTT_RESRV || ((int)reportType) > BTA_HH_RPTT_FEATURE) {
log::error("report type={} not supported", reportType);
- log_counter_metrics_btif(
+ bluetooth::shim::CountCounterMetrics(
android::bluetooth::CodePathCounterKeyEnum::HIDH_COUNT_WRONG_REPORT_TYPE, 1);
return BT_STATUS_UNSUPPORTED;
} else {
diff --git a/system/btif/src/btif_metrics_logging.cc b/system/btif/src/btif_metrics_logging.cc
deleted file mode 100644
index e116cebe28..0000000000
--- a/system/btif/src/btif_metrics_logging.cc
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright 2021 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.
- */
-
-#include "btif/include/btif_metrics_logging.h"
-
-#include <frameworks/proto_logging/stats/enums/bluetooth/enums.pb.h>
-#include <frameworks/proto_logging/stats/enums/bluetooth/hci/enums.pb.h>
-
-#include "main/shim/metrics_api.h"
-#include "types/raw_address.h"
-
-void log_a2dp_audio_underrun_event(const RawAddress& address, uint64_t encoding_interval_millis,
- int num_missing_pcm_bytes) {
- bluetooth::shim::LogMetricA2dpAudioUnderrunEvent(address, encoding_interval_millis,
- num_missing_pcm_bytes);
-}
-
-void log_a2dp_audio_overrun_event(const RawAddress& address, uint64_t encoding_interval_millis,
- int num_dropped_buffers, int num_dropped_encoded_frames,
- int num_dropped_encoded_bytes) {
- bluetooth::shim::LogMetricA2dpAudioOverrunEvent(address, encoding_interval_millis,
- num_dropped_buffers, num_dropped_encoded_frames,
- num_dropped_encoded_bytes);
-}
-
-void log_a2dp_playback_event(const RawAddress& address, int playback_state, int audio_coding_mode) {
- bluetooth::shim::LogMetricA2dpPlaybackEvent(address, playback_state, audio_coding_mode);
-}
-
-void log_a2dp_session_metrics_event(const RawAddress& address, int64_t audio_duration_ms,
- int media_timer_min_ms, int media_timer_max_ms,
- int media_timer_avg_ms, int total_scheduling_count,
- int buffer_overruns_max_count, int buffer_overruns_total,
- float buffer_underruns_average, int buffer_underruns_count,
- int64_t codec_index, bool is_a2dp_offload) {
- bluetooth::shim::LogMetricA2dpSessionMetricsEvent(
- address, audio_duration_ms, media_timer_min_ms, media_timer_max_ms, media_timer_avg_ms,
- total_scheduling_count, buffer_overruns_max_count, buffer_overruns_total,
- buffer_underruns_average, buffer_underruns_count, codec_index, is_a2dp_offload);
-}
-
-void log_read_rssi_result(const RawAddress& address, uint16_t handle, uint32_t cmd_status,
- int8_t rssi) {
- bluetooth::shim::LogMetricReadRssiResult(address, handle, cmd_status, rssi);
-}
-
-void log_read_failed_contact_counter_result(const RawAddress& address, uint16_t handle,
- uint32_t cmd_status, int32_t failed_contact_counter) {
- bluetooth::shim::LogMetricReadFailedContactCounterResult(address, handle, cmd_status,
- failed_contact_counter);
-}
-
-void log_read_tx_power_level_result(const RawAddress& address, uint16_t handle, uint32_t cmd_status,
- int32_t transmit_power_level) {
- bluetooth::shim::LogMetricReadTxPowerLevelResult(address, handle, cmd_status,
- transmit_power_level);
-}
-
-void log_socket_connection_state(const RawAddress& address, int port, int type,
- android::bluetooth::SocketConnectionstateEnum connection_state,
- int64_t tx_bytes, int64_t rx_bytes, int uid, int server_port,
- android::bluetooth::SocketRoleEnum socket_role) {
- bluetooth::shim::LogMetricSocketConnectionState(address, port, type, connection_state, tx_bytes,
- rx_bytes, uid, server_port, socket_role);
-}
-
-void log_counter_metrics_btif(android::bluetooth::CodePathCounterKeyEnum key, int64_t value) {
- bluetooth::shim::CountCounterMetrics(key, value);
-}
-
-bool init_metric_id_allocator(const std::unordered_map<RawAddress, int>& paired_device_map,
- bluetooth::shim::CallbackLegacy save_device_callback,
- bluetooth::shim::CallbackLegacy forget_device_callback) {
- return bluetooth::shim::InitMetricIdAllocator(paired_device_map, std::move(save_device_callback),
- std::move(forget_device_callback));
-}
-
-bool close_metric_id_allocator() { return bluetooth::shim::CloseMetricIdAllocator(); }
-
-int allocate_metric_id_from_metric_id_allocator(const RawAddress& address) {
- return bluetooth::shim::AllocateIdFromMetricIdAllocator(address);
-}
-
-int save_metric_id_from_metric_id_allocator(const RawAddress& address) {
- return bluetooth::shim::SaveDeviceOnMetricIdAllocator(address);
-}
-
-void forget_device_from_metric_id_allocator(const RawAddress& address) {
- bluetooth::shim::ForgetDeviceFromMetricIdAllocator(address);
-}
-
-bool is_valid_id_from_metric_id_allocator(const int id) {
- return bluetooth::shim::IsValidIdFromMetricIdAllocator(id);
-}
diff --git a/system/btif/src/btif_sock.cc b/system/btif/src/btif_sock.cc
index d58326e571..dae8f745c2 100644
--- a/system/btif/src/btif_sock.cc
+++ b/system/btif/src/btif_sock.cc
@@ -177,7 +177,8 @@ static bt_status_t btsock_listen(btsock_type_t type, const char* service_name,
RawAddress::kEmpty, type, channel, app_uid, data_path, hub_id, endpoint_id,
max_rx_packet_size);
btif_sock_connection_logger(RawAddress::kEmpty, 0, type, SOCKET_CONNECTION_STATE_LISTENING,
- SOCKET_ROLE_LISTEN, app_uid, channel, 0, 0, service_name);
+ SOCKET_ROLE_LISTEN, app_uid, channel, 0, 0, service_name, 0,
+ BTSOCK_ERROR_NONE, data_path);
switch (type) {
case BTSOCK_RFCOMM:
status = btsock_rfc_listen(service_name, service_uuid, channel, sock_fd, flags, app_uid,
@@ -207,7 +208,8 @@ static bt_status_t btsock_listen(btsock_type_t type, const char* service_name,
"channel: {}, app_uid: {}",
RawAddress::kEmpty, type, channel, app_uid);
btif_sock_connection_logger(RawAddress::kEmpty, 0, type, SOCKET_CONNECTION_STATE_DISCONNECTED,
- SOCKET_ROLE_LISTEN, app_uid, channel, 0, 0, service_name);
+ SOCKET_ROLE_LISTEN, app_uid, channel, 0, 0, service_name, 0,
+ BTSOCK_ERROR_LISTEN_FAILURE, data_path);
}
return status;
}
@@ -227,9 +229,9 @@ static bt_status_t btsock_connect(const RawAddress* bd_addr, btsock_type_t type,
*sock_fd = INVALID_FD;
bt_status_t status = BT_STATUS_SOCKET_ERROR;
- btif_sock_connection_logger(*bd_addr, 0, type, SOCKET_CONNECTION_STATE_CONNECTING,
- SOCKET_ROLE_CONNECTION, app_uid, channel, 0, 0,
- uuid ? uuid->ToString().c_str() : "");
+ btif_sock_connection_logger(
+ *bd_addr, 0, type, SOCKET_CONNECTION_STATE_CONNECTING, SOCKET_ROLE_CONNECTION, app_uid,
+ channel, 0, 0, uuid ? uuid->ToString().c_str() : "", 0, BTSOCK_ERROR_NONE, data_path);
switch (type) {
case BTSOCK_RFCOMM:
status = btsock_rfc_connect(bd_addr, uuid, channel, sock_fd, flags, app_uid, data_path,
@@ -261,7 +263,8 @@ static bt_status_t btsock_connect(const RawAddress* bd_addr, btsock_type_t type,
*bd_addr, type, channel, app_uid);
btif_sock_connection_logger(*bd_addr, 0, type, SOCKET_CONNECTION_STATE_DISCONNECTED,
SOCKET_ROLE_CONNECTION, app_uid, channel, 0, 0,
- uuid ? uuid->ToString().c_str() : "");
+ uuid ? uuid->ToString().c_str() : "", 0,
+ BTSOCK_ERROR_CONNECTION_FAILURE, data_path);
}
return status;
}
diff --git a/system/btif/src/btif_sock_l2cap.cc b/system/btif/src/btif_sock_l2cap.cc
index d607ff3b74..3867727cdb 100644
--- a/system/btif/src/btif_sock_l2cap.cc
+++ b/system/btif/src/btif_sock_l2cap.cc
@@ -35,6 +35,7 @@
#include "btif/include/btif_sock_thread.h"
#include "btif/include/btif_sock_util.h"
#include "btif/include/btif_uid.h"
+#include "common/time_util.h"
#include "gd/os/rand.h"
#include "include/hardware/bluetooth.h"
#include "internal_include/bt_target.h"
@@ -92,6 +93,7 @@ typedef struct l2cap_socket {
uint64_t hub_id; // ID of the hub to which the end point belongs
uint64_t endpoint_id; // ID of the hub end point
bool is_accepting; // is app accepting on server socket?
+ uint64_t connection_start_time_ms; // Timestamp when the connection state started
} l2cap_socket;
static void btsock_l2cap_server_listen(l2cap_socket* sock);
@@ -238,7 +240,7 @@ static l2cap_socket* btsock_l2cap_find_by_conn_uuid_l(Uuid& conn_uuid) {
return nullptr;
}
-static void btsock_l2cap_free_l(l2cap_socket* sock) {
+static void btsock_l2cap_free_l(l2cap_socket* sock, btsock_error_code_t error_code) {
uint8_t* buf;
l2cap_socket* t = socks;
@@ -258,7 +260,8 @@ static void btsock_l2cap_free_l(l2cap_socket* sock) {
sock->addr, sock->id, sock->is_le_coc ? BTSOCK_L2CAP_LE : BTSOCK_L2CAP,
SOCKET_CONNECTION_STATE_DISCONNECTED,
sock->server ? SOCKET_ROLE_LISTEN : SOCKET_ROLE_CONNECTION, sock->app_uid, sock->channel,
- sock->tx_bytes, sock->rx_bytes, sock->name);
+ sock->tx_bytes, sock->rx_bytes, sock->name, sock->connection_start_time_ms, error_code,
+ sock->data_path);
if (com::android::bluetooth::flags::socket_settings_api()) {
if (sock->data_path == BTSOCK_DATA_PATH_HARDWARE_OFFLOAD && !sock->server &&
sock->socket_id != 0) {
@@ -359,6 +362,7 @@ static l2cap_socket* btsock_l2cap_alloc_l(const char* name, const RawAddress* ad
sock->hub_id = 0;
sock->endpoint_id = 0;
sock->is_accepting = false;
+ sock->connection_start_time_ms = 0;
if (name) {
strncpy(sock->name, name, sizeof(sock->name) - 1);
@@ -418,7 +422,7 @@ bt_status_t btsock_l2cap_cleanup() {
std::unique_lock<std::mutex> lock(state_lock);
pth = -1;
while (socks) {
- btsock_l2cap_free_l(socks);
+ btsock_l2cap_free_l(socks, BTSOCK_ERROR_NONE);
}
return BT_STATUS_SUCCESS;
}
@@ -500,7 +504,7 @@ static void on_srv_l2cap_listen_started(tBTA_JV_L2CAP_START* p_start, uint32_t i
if (p_start->status != tBTA_JV_STATUS::SUCCESS) {
log::error("Unable to start l2cap server socket_id:{}", sock->id);
- btsock_l2cap_free_l(sock);
+ btsock_l2cap_free_l(sock, BTSOCK_ERROR_SERVER_START_FAILURE);
return;
}
@@ -510,17 +514,17 @@ static void on_srv_l2cap_listen_started(tBTA_JV_L2CAP_START* p_start, uint32_t i
"Listening for L2CAP connection for device: {}, channel: {}, app_uid: "
"{}, id: {}, is_le: {}",
sock->addr, sock->channel, sock->app_uid, sock->id, sock->is_le_coc);
- btif_sock_connection_logger(sock->addr, sock->id,
- sock->is_le_coc ? BTSOCK_L2CAP_LE : BTSOCK_L2CAP,
- SOCKET_CONNECTION_STATE_LISTENING,
- sock->server ? SOCKET_ROLE_LISTEN : SOCKET_ROLE_CONNECTION,
- sock->app_uid, sock->channel, 0, 0, sock->name);
+ btif_sock_connection_logger(
+ sock->addr, sock->id, sock->is_le_coc ? BTSOCK_L2CAP_LE : BTSOCK_L2CAP,
+ SOCKET_CONNECTION_STATE_LISTENING,
+ sock->server ? SOCKET_ROLE_LISTEN : SOCKET_ROLE_CONNECTION, sock->app_uid, sock->channel,
+ 0, 0, sock->name, 0, BTSOCK_ERROR_NONE, sock->data_path);
if (!sock->server_psm_sent) {
if (!send_app_psm_or_chan_l(sock)) {
// closed
log::info("Unable to send socket to application socket_id:{}", sock->id);
- btsock_l2cap_free_l(sock);
+ btsock_l2cap_free_l(sock, BTSOCK_ERROR_SEND_TO_APP_FAILURE);
} else {
sock->server_psm_sent = true;
}
@@ -539,7 +543,7 @@ static void on_cl_l2cap_init(tBTA_JV_L2CAP_CL_INIT* p_init, uint32_t id) {
if (p_init->status != tBTA_JV_STATUS::SUCCESS) {
log::error("Initialization status failed socket_id:{}", id);
- btsock_l2cap_free_l(sock);
+ btsock_l2cap_free_l(sock, BTSOCK_ERROR_CLIENT_INIT_FAILURE);
return;
}
@@ -589,11 +593,12 @@ static void on_srv_l2cap_psm_connect_l(tBTA_JV_L2CAP_OPEN* p_open, l2cap_socket*
"id: {}, is_le: {}, socket_id: {}, rx_mtu: {}",
accept_rs->addr, accept_rs->channel, accept_rs->app_uid, accept_rs->id,
accept_rs->is_le_coc, accept_rs->socket_id, accept_rs->rx_mtu);
- btif_sock_connection_logger(accept_rs->addr, accept_rs->id,
- accept_rs->is_le_coc ? BTSOCK_L2CAP_LE : BTSOCK_L2CAP,
- SOCKET_CONNECTION_STATE_CONNECTED,
- accept_rs->server ? SOCKET_ROLE_LISTEN : SOCKET_ROLE_CONNECTION,
- accept_rs->app_uid, accept_rs->channel, 0, 0, accept_rs->name);
+ btif_sock_connection_logger(
+ accept_rs->addr, accept_rs->id, accept_rs->is_le_coc ? BTSOCK_L2CAP_LE : BTSOCK_L2CAP,
+ SOCKET_CONNECTION_STATE_CONNECTED,
+ accept_rs->server ? SOCKET_ROLE_LISTEN : SOCKET_ROLE_CONNECTION, accept_rs->app_uid,
+ accept_rs->channel, 0, 0, accept_rs->name, 0, BTSOCK_ERROR_NONE, accept_rs->data_path);
+ accept_rs->connection_start_time_ms = common::time_gettimeofday_us() / 1000;
// start monitor the socket
btsock_thread_add_fd(pth, sock->our_fd, BTSOCK_L2CAP, SOCK_THREAD_FD_EXCEPTION, sock->id);
@@ -638,11 +643,12 @@ static void on_cl_l2cap_psm_connect_l(tBTA_JV_L2CAP_OPEN* p_open, l2cap_socket*
"id: {}, is_le: {}, socket_id: {}, rx_mtu: {}",
sock->addr, sock->channel, sock->app_uid, sock->id, sock->is_le_coc, sock->socket_id,
sock->rx_mtu);
- btif_sock_connection_logger(sock->addr, sock->id,
- sock->is_le_coc ? BTSOCK_L2CAP_LE : BTSOCK_L2CAP,
- SOCKET_CONNECTION_STATE_CONNECTED,
- sock->server ? SOCKET_ROLE_LISTEN : SOCKET_ROLE_CONNECTION,
- sock->app_uid, sock->channel, 0, 0, sock->name);
+ btif_sock_connection_logger(
+ sock->addr, sock->id, sock->is_le_coc ? BTSOCK_L2CAP_LE : BTSOCK_L2CAP,
+ SOCKET_CONNECTION_STATE_CONNECTED,
+ sock->server ? SOCKET_ROLE_LISTEN : SOCKET_ROLE_CONNECTION, sock->app_uid, sock->channel,
+ 0, 0, sock->name, 0, BTSOCK_ERROR_NONE, sock->data_path);
+ sock->connection_start_time_ms = common::time_gettimeofday_us() / 1000;
// start monitoring the socketpair to get call back when app writing data
btsock_thread_add_fd(pth, sock->our_fd, BTSOCK_L2CAP, SOCK_THREAD_FD_RD, sock->id);
@@ -679,7 +685,7 @@ static void on_l2cap_connect(tBTA_JV* p_data, uint32_t id) {
}
} else {
log::error("Unable to open socket after receiving connection socket_id:{}", sock->id);
- btsock_l2cap_free_l(sock);
+ btsock_l2cap_free_l(sock, BTSOCK_ERROR_OPEN_FAILURE);
}
}
@@ -697,11 +703,11 @@ static void on_l2cap_close(tBTA_JV_L2CAP_CLOSE* p_close, uint32_t id) {
"Disconnecting from L2CAP connection for device: {}, channel: {}, "
"app_uid: {}, id: {}, is_le: {}",
sock->addr, sock->channel, sock->app_uid, sock->id, sock->is_le_coc);
- btif_sock_connection_logger(sock->addr, sock->id,
- sock->is_le_coc ? BTSOCK_L2CAP_LE : BTSOCK_L2CAP,
- SOCKET_CONNECTION_STATE_DISCONNECTING,
- sock->server ? SOCKET_ROLE_LISTEN : SOCKET_ROLE_CONNECTION,
- sock->app_uid, sock->channel, 0, 0, sock->name);
+ btif_sock_connection_logger(
+ sock->addr, sock->id, sock->is_le_coc ? BTSOCK_L2CAP_LE : BTSOCK_L2CAP,
+ SOCKET_CONNECTION_STATE_DISCONNECTING,
+ sock->server ? SOCKET_ROLE_LISTEN : SOCKET_ROLE_CONNECTION, sock->app_uid, sock->channel,
+ 0, 0, sock->name, 0, BTSOCK_ERROR_NONE, sock->data_path);
if (com::android::bluetooth::flags::donot_push_error_code_to_app_when_connected()) {
if (!sock->connected) {
if (!send_app_err_code(sock, p_close->reason)) {
@@ -720,7 +726,7 @@ static void on_l2cap_close(tBTA_JV_L2CAP_CLOSE* p_close, uint32_t id) {
if (sock->server) {
BTA_JvFreeChannel(sock->channel, tBTA_JV_CONN_TYPE::L2CAP);
}
- btsock_l2cap_free_l(sock);
+ btsock_l2cap_free_l(sock, BTSOCK_ERROR_NONE);
}
static void on_l2cap_outgoing_congest(tBTA_JV_L2CAP_CONG* p, uint32_t id) {
@@ -786,7 +792,7 @@ static void on_l2cap_data_ind(tBTA_JV* /* evt */, uint32_t id) {
} else { // connection must be dropped
log::warn("Closing socket as unable to push data to socket socket_id:{}", sock->id);
BTA_JvL2capClose(sock->handle);
- btsock_l2cap_free_l(sock);
+ btsock_l2cap_free_l(sock, BTSOCK_ERROR_RECEIVE_DATA_FAILURE);
return;
}
}
@@ -1151,6 +1157,7 @@ static bool btsock_l2cap_read_signaled_on_listen_socket(int fd, int /* flags */,
static void btsock_l2cap_signaled_flagged(int fd, int flags, uint32_t user_id) {
char drop_it = false;
+ btsock_error_code_t error_code = BTSOCK_ERROR_NONE;
/* We use MSG_DONTWAIT when sending data to JAVA, hence it can be accepted to
* hold the lock. */
@@ -1163,11 +1170,13 @@ static void btsock_l2cap_signaled_flagged(int fd, int flags, uint32_t user_id) {
if (!sock->server) {
// app sending data on connection socket
if (!btsock_l2cap_read_signaled_on_connected_socket(fd, flags, user_id, sock)) {
+ error_code = BTSOCK_ERROR_READ_SIGNALED_FAILURE;
drop_it = true;
}
} else {
// app sending signal on listen socket
if (!btsock_l2cap_read_signaled_on_listen_socket(fd, flags, user_id, sock)) {
+ error_code = BTSOCK_ERROR_READ_SIGNALED_FAILURE;
drop_it = true;
}
}
@@ -1181,7 +1190,7 @@ static void btsock_l2cap_signaled_flagged(int fd, int flags, uint32_t user_id) {
if (drop_it || (flags & SOCK_THREAD_FD_EXCEPTION)) {
int size = 0;
if (drop_it || ioctl(sock->our_fd, FIONREAD, &size) != 0 || size == 0) {
- btsock_l2cap_free_l(sock);
+ btsock_l2cap_free_l(sock, error_code);
}
}
}
@@ -1192,6 +1201,7 @@ void btsock_l2cap_signaled(int fd, int flags, uint32_t user_id) {
return;
}
char drop_it = false;
+ btsock_error_code_t error_code = BTSOCK_ERROR_NONE;
/* We use MSG_DONTWAIT when sending data to JAVA, hence it can be accepted to
* hold the lock. */
@@ -1238,6 +1248,7 @@ void btsock_l2cap_signaled(int fd, int flags, uint32_t user_id) {
BTA_JvL2capWrite(sock->handle, PTR_TO_UINT(buffer), buffer, user_id);
}
} else {
+ error_code = BTSOCK_ERROR_READ_SIGNALED_FAILURE;
drop_it = true;
}
}
@@ -1250,7 +1261,7 @@ void btsock_l2cap_signaled(int fd, int flags, uint32_t user_id) {
if (drop_it || (flags & SOCK_THREAD_FD_EXCEPTION)) {
int size = 0;
if (drop_it || ioctl(sock->our_fd, FIONREAD, &size) != 0 || size == 0) {
- btsock_l2cap_free_l(sock);
+ btsock_l2cap_free_l(sock, error_code);
}
}
}
@@ -1269,7 +1280,7 @@ bt_status_t btsock_l2cap_disconnect(const RawAddress* bd_addr) {
while (sock) {
l2cap_socket* next = sock->next;
if (sock->addr == *bd_addr) {
- btsock_l2cap_free_l(sock);
+ btsock_l2cap_free_l(sock, BTSOCK_ERROR_NONE);
}
sock = next;
}
@@ -1343,7 +1354,7 @@ void on_btsocket_l2cap_opened_complete(uint64_t socket_id, bool success) {
}
if (!success) {
log::error("L2CAP opened complete failed with socket_id:{}", socket_id);
- btsock_l2cap_free_l(sock);
+ btsock_l2cap_free_l(sock, BTSOCK_ERROR_OPEN_FAILURE);
return;
}
// If the socket was accepted from listen socket, use listen_fd.
@@ -1368,11 +1379,12 @@ void on_btsocket_l2cap_opened_complete(uint64_t socket_id, bool success) {
"is_le: {}, socket_id: {}, rx_mtu: {}",
sock->addr, sock->channel, sock->app_uid, sock->id, sock->is_le_coc, sock->socket_id,
sock->rx_mtu);
- btif_sock_connection_logger(sock->addr, sock->id,
- sock->is_le_coc ? BTSOCK_L2CAP_LE : BTSOCK_L2CAP,
- SOCKET_CONNECTION_STATE_CONNECTED,
- sock->server ? SOCKET_ROLE_LISTEN : SOCKET_ROLE_CONNECTION,
- sock->app_uid, sock->channel, 0, 0, sock->name);
+ btif_sock_connection_logger(
+ sock->addr, sock->id, sock->is_le_coc ? BTSOCK_L2CAP_LE : BTSOCK_L2CAP,
+ SOCKET_CONNECTION_STATE_CONNECTED,
+ sock->server ? SOCKET_ROLE_LISTEN : SOCKET_ROLE_CONNECTION, sock->app_uid,
+ sock->channel, 0, 0, sock->name, 0, BTSOCK_ERROR_NONE, sock->data_path);
+ sock->connection_start_time_ms = common::time_gettimeofday_us() / 1000;
log::info("Connected l2cap socket socket_id:{}", sock->id);
sock->connected = true;
@@ -1389,7 +1401,7 @@ void on_btsocket_l2cap_close(uint64_t socket_id) {
return;
}
log::info("L2CAP close request for socket_id:{}", socket_id);
- btsock_l2cap_free_l(sock);
+ btsock_l2cap_free_l(sock, BTSOCK_ERROR_NONE);
}
static void on_cl_l2cap_psm_connect_offload_l(tBTA_JV_L2CAP_OPEN* p_open, l2cap_socket* sock) {
@@ -1407,11 +1419,12 @@ static void on_cl_l2cap_psm_connect_offload_l(tBTA_JV_L2CAP_OPEN* p_open, l2cap_
"id: {}, is_le: {}, socket_id: {}, rx_mtu: {}",
sock->addr, sock->channel, sock->app_uid, sock->id, sock->is_le_coc, sock->socket_id,
sock->rx_mtu);
- btif_sock_connection_logger(sock->addr, sock->id,
- sock->is_le_coc ? BTSOCK_L2CAP_LE : BTSOCK_L2CAP,
- SOCKET_CONNECTION_STATE_CONNECTED,
- sock->server ? SOCKET_ROLE_LISTEN : SOCKET_ROLE_CONNECTION,
- sock->app_uid, sock->channel, 0, 0, sock->name);
+ btif_sock_connection_logger(
+ sock->addr, sock->id, sock->is_le_coc ? BTSOCK_L2CAP_LE : BTSOCK_L2CAP,
+ SOCKET_CONNECTION_STATE_CONNECTED,
+ sock->server ? SOCKET_ROLE_LISTEN : SOCKET_ROLE_CONNECTION, sock->app_uid, sock->channel,
+ 0, 0, sock->name, 0, BTSOCK_ERROR_NONE, sock->data_path);
+ sock->connection_start_time_ms = common::time_gettimeofday_us() / 1000;
bluetooth::hal::SocketContext socket_context = {
.socket_id = sock->socket_id,
@@ -1426,7 +1439,7 @@ static void on_cl_l2cap_psm_connect_offload_l(tBTA_JV_L2CAP_OPEN* p_open, l2cap_
};
if (!bluetooth::shim::GetLppOffloadManager()->SocketOpened(socket_context)) {
log::warn("L2CAP socket opened failed. Disconnect the incoming connection.");
- btsock_l2cap_free_l(sock);
+ btsock_l2cap_free_l(sock, BTSOCK_ERROR_OFFLOAD_HAL_OPEN_FAILURE);
} else {
log::info(
"L2CAP socket opened successful. Will send connect signal in "
@@ -1470,11 +1483,12 @@ static void on_srv_l2cap_psm_connect_offload_l(tBTA_JV_L2CAP_OPEN* p_open, l2cap
"id: {}, is_le: {}, socket_id: {}, rx_mtu: {}",
accept_rs->addr, accept_rs->channel, accept_rs->app_uid, accept_rs->id,
accept_rs->is_le_coc, accept_rs->socket_id, accept_rs->rx_mtu);
- btif_sock_connection_logger(accept_rs->addr, accept_rs->id,
- accept_rs->is_le_coc ? BTSOCK_L2CAP_LE : BTSOCK_L2CAP,
- SOCKET_CONNECTION_STATE_CONNECTED,
- accept_rs->server ? SOCKET_ROLE_LISTEN : SOCKET_ROLE_CONNECTION,
- accept_rs->app_uid, accept_rs->channel, 0, 0, accept_rs->name);
+ btif_sock_connection_logger(
+ accept_rs->addr, accept_rs->id, accept_rs->is_le_coc ? BTSOCK_L2CAP_LE : BTSOCK_L2CAP,
+ SOCKET_CONNECTION_STATE_CONNECTED,
+ accept_rs->server ? SOCKET_ROLE_LISTEN : SOCKET_ROLE_CONNECTION, accept_rs->app_uid,
+ accept_rs->channel, 0, 0, accept_rs->name, 0, BTSOCK_ERROR_NONE, accept_rs->data_path);
+ accept_rs->connection_start_time_ms = common::time_gettimeofday_us() / 1000;
bluetooth::hal::SocketContext socket_context = {
.socket_id = accept_rs->socket_id,
@@ -1489,10 +1503,10 @@ static void on_srv_l2cap_psm_connect_offload_l(tBTA_JV_L2CAP_OPEN* p_open, l2cap
};
if (!sock->is_accepting) {
log::warn("Server socket is not accepting. Disconnect the incoming connection.");
- btsock_l2cap_free_l(accept_rs);
+ btsock_l2cap_free_l(accept_rs, BTSOCK_ERROR_OFFLOAD_SERVER_NOT_ACCEPTING);
} else if (!bluetooth::shim::GetLppOffloadManager()->SocketOpened(socket_context)) {
log::warn("L2CAP socket opened failed. Disconnect the incoming connection.");
- btsock_l2cap_free_l(accept_rs);
+ btsock_l2cap_free_l(accept_rs, BTSOCK_ERROR_OFFLOAD_HAL_OPEN_FAILURE);
} else {
log::info("L2CAP socket opened successful. Will send connect signal in async callback.");
}
diff --git a/system/btif/src/btif_sock_logging.cc b/system/btif/src/btif_sock_logging.cc
index acb38f7de5..8847daa7f1 100644
--- a/system/btif/src/btif_sock_logging.cc
+++ b/system/btif/src/btif_sock_logging.cc
@@ -23,8 +23,9 @@
#include <atomic>
-#include "btif/include/btif_metrics_logging.h"
#include "btif/include/btif_sock.h"
+#include "common/time_util.h"
+#include "main/shim/metrics_api.h"
#include "types/raw_address.h"
#define SOCK_LOGGER_SIZE_MAX 16
@@ -50,11 +51,15 @@ static SockConnectionEvent connection_logger[SOCK_LOGGER_SIZE_MAX];
static android::bluetooth::SocketConnectionstateEnum toConnectionStateEnum(int state);
static android::bluetooth::SocketRoleEnum toSocketRoleEnum(int role);
+static android::bluetooth::SocketErrorEnum toSocketErrorEnum(btsock_error_code_t error_code);
+static uint64_t getConnectionDuration(uint64_t start_time_ms);
void btif_sock_connection_logger(const RawAddress& address, int port, int type, int state, int role,
int uid, int server_port, int64_t tx_bytes, int64_t rx_bytes,
- const char* server_name) {
- log::verbose("bd_addr: {}, port: {}, role: {}, state: {}", address, port, role, state);
+ const char* server_name, uint64_t connection_start_time_ms,
+ btsock_error_code_t error_code, btsock_data_path_t data_path) {
+ log::verbose("bd_addr: {}, port: {}, role: {}, state: {}, data_path: {}", address, port, role,
+ state, data_path);
uint8_t index = logger_index++ % SOCK_LOGGER_SIZE_MAX;
@@ -74,8 +79,10 @@ void btif_sock_connection_logger(const RawAddress& address, int port, int type,
}
clock_gettime(CLOCK_REALTIME, &connection_logger[index].timestamp);
- log_socket_connection_state(address, port, type, toConnectionStateEnum(state), tx_bytes, rx_bytes,
- uid, server_port, toSocketRoleEnum(role));
+ bluetooth::shim::LogMetricSocketConnectionState(
+ address, port, type, toConnectionStateEnum(state), tx_bytes, rx_bytes, uid, server_port,
+ toSocketRoleEnum(role), getConnectionDuration(connection_start_time_ms),
+ toSocketErrorEnum(error_code), data_path == BTSOCK_DATA_PATH_HARDWARE_OFFLOAD);
}
void btif_sock_dump(int fd) {
@@ -192,3 +199,54 @@ static android::bluetooth::SocketRoleEnum toSocketRoleEnum(int role) {
}
return android::bluetooth::SOCKET_ROLE_UNKNOWN;
}
+
+static android::bluetooth::SocketErrorEnum toSocketErrorEnum(btsock_error_code_t error_code) {
+ switch (error_code) {
+ case BTSOCK_ERROR_NONE:
+ return android::bluetooth::SocketErrorEnum::SOCKET_ERROR_NONE;
+ case BTSOCK_ERROR_SERVER_START_FAILURE:
+ return android::bluetooth::SocketErrorEnum::SOCKET_ERROR_SERVER_START_FAILURE;
+ case BTSOCK_ERROR_CLIENT_INIT_FAILURE:
+ return android::bluetooth::SocketErrorEnum::SOCKET_ERROR_CLIENT_INIT_FAILURE;
+ case BTSOCK_ERROR_LISTEN_FAILURE:
+ return android::bluetooth::SocketErrorEnum::SOCKET_ERROR_LISTEN_FAILURE;
+ case BTSOCK_ERROR_CONNECTION_FAILURE:
+ return android::bluetooth::SocketErrorEnum::SOCKET_ERROR_CONNECTION_FAILURE;
+ case BTSOCK_ERROR_OPEN_FAILURE:
+ return android::bluetooth::SocketErrorEnum::SOCKET_ERROR_OPEN_FAILURE;
+ case BTSOCK_ERROR_OFFLOAD_SERVER_NOT_ACCEPTING:
+ return android::bluetooth::SocketErrorEnum::SOCKET_ERROR_OFFLOAD_SERVER_NOT_ACCEPTING;
+ case BTSOCK_ERROR_OFFLOAD_HAL_OPEN_FAILURE:
+ return android::bluetooth::SocketErrorEnum::SOCKET_ERROR_OFFLOAD_HAL_OPEN_FAILURE;
+ case BTSOCK_ERROR_SEND_TO_APP_FAILURE:
+ return android::bluetooth::SocketErrorEnum::SOCKET_ERROR_SEND_TO_APP_FAILURE;
+ case BTSOCK_ERROR_RECEIVE_DATA_FAILURE:
+ return android::bluetooth::SocketErrorEnum::SOCKET_ERROR_RECEIVE_DATA_FAILURE;
+ case BTSOCK_ERROR_READ_SIGNALED_FAILURE:
+ return android::bluetooth::SocketErrorEnum::SOCKET_ERROR_READ_SIGNALED_FAILURE;
+ case BTSOCK_ERROR_WRITE_SIGNALED_FAILURE:
+ return android::bluetooth::SocketErrorEnum::SOCKET_ERROR_WRITE_SIGNALED_FAILURE;
+ case BTSOCK_ERROR_SEND_SCN_FAILURE:
+ return android::bluetooth::SocketErrorEnum::SOCKET_ERROR_SEND_SCN_FAILURE;
+ case BTSOCK_ERROR_SCN_ALLOCATION_FAILURE:
+ return android::bluetooth::SocketErrorEnum::SOCKET_ERROR_SCN_ALLOCATION_FAILURE;
+ case BTSOCK_ERROR_ADD_SDP_FAILURE:
+ return android::bluetooth::SocketErrorEnum::SOCKET_ERROR_ADD_SDP_FAILURE;
+ case BTSOCK_ERROR_SDP_DISCOVERY_FAILURE:
+ return android::bluetooth::SocketErrorEnum::SOCKET_ERROR_SDP_DISCOVERY_FAILURE;
+ }
+ return android::bluetooth::SocketErrorEnum::SOCKET_ERROR_NONE;
+}
+
+static uint64_t getConnectionDuration(uint64_t start_time_ms) {
+ // start time is 0 before the connection state, use 0 for duration
+ if (start_time_ms == 0) {
+ return 0;
+ }
+ uint64_t current_time_ms = common::time_gettimeofday_us() / 1000;
+ if (current_time_ms <= start_time_ms) {
+ log::warn("Socket connection end time is not greater than start time, logging 0 ms instead");
+ return 0;
+ }
+ return current_time_ms - start_time_ms;
+}
diff --git a/system/btif/src/btif_sock_rfc.cc b/system/btif/src/btif_sock_rfc.cc
index 929ce8a3cc..1ea4bf9981 100644
--- a/system/btif/src/btif_sock_rfc.cc
+++ b/system/btif/src/btif_sock_rfc.cc
@@ -33,7 +33,6 @@
#include "bta/include/bta_jv_co.h"
#include "bta/include/bta_rfcomm_metrics.h"
#include "bta/include/bta_rfcomm_scn.h"
-#include "btif/include/btif_metrics_logging.h"
#include "btif/include/btif_sock.h"
#include "btif/include/btif_sock_l2cap.h"
#include "btif/include/btif_sock_logging.h"
@@ -45,6 +44,7 @@
#include "include/hardware/bt_sock.h"
#include "lpp/lpp_offload_interface.h"
#include "main/shim/entry.h"
+#include "main/shim/metrics_api.h"
#include "osi/include/allocator.h"
#include "osi/include/compat.h"
#include "osi/include/list.h"
@@ -106,6 +106,7 @@ typedef struct {
uint64_t hub_id; // ID of the hub to which the end point belongs
uint64_t endpoint_id; // ID of the hub end point
bool is_accepting; // is app accepting on server socket?
+ uint64_t connection_start_time_ms; // Timestamp when the connection state started
} rfc_slot_t;
static rfc_slot_t rfc_slots[MAX_RFC_CHANNEL];
@@ -115,7 +116,7 @@ static std::recursive_mutex slot_lock;
static uid_set_t* uid_set = NULL;
static rfc_slot_t* find_free_slot(void);
-static void cleanup_rfc_slot(rfc_slot_t* rs);
+static void cleanup_rfc_slot(rfc_slot_t* rs, btsock_error_code_t error_code);
static void jv_dm_cback(tBTA_JV_EVT event, tBTA_JV* p_data, uint32_t id);
static uint32_t rfcomm_cback(tBTA_JV_EVT event, tBTA_JV* p_data, uint32_t rfcomm_slot_id);
static bool send_app_scn(rfc_slot_t* rs);
@@ -152,7 +153,7 @@ void btsock_rfc_cleanup(void) {
std::unique_lock<std::recursive_mutex> lock(slot_lock);
for (size_t i = 0; i < ARRAY_SIZE(rfc_slots); ++i) {
if (rfc_slots[i].id) {
- cleanup_rfc_slot(&rfc_slots[i]);
+ cleanup_rfc_slot(&rfc_slots[i], BTSOCK_ERROR_NONE);
}
list_free(rfc_slots[i].incoming_queue);
rfc_slots[i].incoming_queue = NULL;
@@ -251,6 +252,7 @@ static rfc_slot_t* alloc_rfc_slot(const RawAddress* addr, const char* name, cons
slot->hub_id = 0;
slot->endpoint_id = 0;
slot->is_accepting = false;
+ slot->connection_start_time_ms = 0;
slot->is_service_uuid_valid = !uuid.IsEmpty();
slot->service_uuid = uuid;
@@ -466,13 +468,13 @@ bt_status_t btsock_rfc_connect(const RawAddress* bd_addr, const Uuid* service_uu
if (ret != tBTA_JV_STATUS::SUCCESS) {
log::error("unable to initiate RFCOMM connection. status:{}, scn:{}, bd_addr:{}",
bta_jv_status_text(ret), slot->scn, slot->addr);
- cleanup_rfc_slot(slot);
+ cleanup_rfc_slot(slot, BTSOCK_ERROR_CONNECTION_FAILURE);
return BT_STATUS_SOCKET_ERROR;
}
if (!send_app_scn(slot)) {
log::error("send_app_scn() failed, closing slot_id:{}", slot->id);
- cleanup_rfc_slot(slot);
+ cleanup_rfc_slot(slot, BTSOCK_ERROR_SEND_SCN_FAILURE);
return BT_STATUS_SOCKET_ERROR;
}
} else {
@@ -535,7 +537,7 @@ static void free_rfc_slot_scn(rfc_slot_t* slot) {
slot->scn = 0;
}
-static void cleanup_rfc_slot(rfc_slot_t* slot) {
+static void cleanup_rfc_slot(rfc_slot_t* slot, btsock_error_code_t error_code) {
if (slot->fd != INVALID_FD) {
shutdown(slot->fd, SHUT_RDWR);
close(slot->fd);
@@ -547,7 +549,8 @@ static void cleanup_rfc_slot(rfc_slot_t* slot) {
slot->addr, slot->id, BTSOCK_RFCOMM, SOCKET_CONNECTION_STATE_DISCONNECTED,
slot->f.server ? SOCKET_ROLE_LISTEN : SOCKET_ROLE_CONNECTION, slot->app_uid, slot->scn,
slot->tx_bytes, slot->rx_bytes,
- slot->role ? slot->service_name : slot->service_uuid.ToString().c_str());
+ slot->role ? slot->service_name : slot->service_uuid.ToString().c_str(),
+ slot->connection_start_time_ms, error_code, slot->data_path);
slot->fd = INVALID_FD;
@@ -625,7 +628,7 @@ static void on_cl_rfc_init(tBTA_JV_RFCOMM_CL_INIT* p_init, uint32_t id) {
} else if (p_init->status != tBTA_JV_STATUS::SUCCESS) {
log::warn("INIT unsuccessful, status {}. Cleaning up slot_id {}",
bta_jv_status_text(p_init->status), slot->id);
- cleanup_rfc_slot(slot);
+ cleanup_rfc_slot(slot, BTSOCK_ERROR_CLIENT_INIT_FAILURE);
} else {
slot->rfc_handle = p_init->handle;
}
@@ -640,7 +643,7 @@ static void on_srv_rfc_listen_started(tBTA_JV_RFCOMM_START* p_start, uint32_t id
} else if (p_start->status != tBTA_JV_STATUS::SUCCESS) {
log::warn("START unsuccessful, status {}. Cleaning up slot_id {}",
bta_jv_status_text(p_start->status), slot->id);
- cleanup_rfc_slot(slot);
+ cleanup_rfc_slot(slot, BTSOCK_ERROR_SERVER_START_FAILURE);
return;
}
@@ -649,10 +652,10 @@ static void on_srv_rfc_listen_started(tBTA_JV_RFCOMM_START* p_start, uint32_t id
"listening for RFCOMM socket connections for device: {}, scn: {}, "
"app_uid: {}, id: {}",
slot->addr, slot->scn, slot->app_uid, id);
- btif_sock_connection_logger(slot->addr, slot->id, BTSOCK_RFCOMM,
- SOCKET_CONNECTION_STATE_LISTENING,
- slot->f.server ? SOCKET_ROLE_LISTEN : SOCKET_ROLE_CONNECTION,
- slot->app_uid, slot->scn, 0, 0, slot->service_name);
+ btif_sock_connection_logger(
+ slot->addr, slot->id, BTSOCK_RFCOMM, SOCKET_CONNECTION_STATE_LISTENING,
+ slot->f.server ? SOCKET_ROLE_LISTEN : SOCKET_ROLE_CONNECTION, slot->app_uid, slot->scn, 0,
+ 0, slot->service_name, 0, BTSOCK_ERROR_NONE, slot->data_path);
}
static uint32_t on_srv_rfc_connect_offload(tBTA_JV_RFCOMM_SRV_OPEN* p_open, rfc_slot_t* srv_rs) {
@@ -670,7 +673,9 @@ static uint32_t on_srv_rfc_connect_offload(tBTA_JV_RFCOMM_SRV_OPEN* p_open, rfc_
btif_sock_connection_logger(accept_rs->addr, accept_rs->id, BTSOCK_RFCOMM,
SOCKET_CONNECTION_STATE_CONNECTED,
accept_rs->f.server ? SOCKET_ROLE_LISTEN : SOCKET_ROLE_CONNECTION,
- accept_rs->app_uid, accept_rs->scn, 0, 0, accept_rs->service_name);
+ accept_rs->app_uid, accept_rs->scn, 0, 0, accept_rs->service_name, 0,
+ BTSOCK_ERROR_NONE, accept_rs->data_path);
+ accept_rs->connection_start_time_ms = common::time_gettimeofday_us() / 1000;
bluetooth::hal::SocketContext socket_context = {
.socket_id = accept_rs->socket_id,
@@ -685,10 +690,10 @@ static uint32_t on_srv_rfc_connect_offload(tBTA_JV_RFCOMM_SRV_OPEN* p_open, rfc_
};
if (!srv_rs->is_accepting) {
log::warn("Server socket is not accepting. Disconnect the incoming connection.");
- cleanup_rfc_slot(accept_rs);
+ cleanup_rfc_slot(accept_rs, BTSOCK_ERROR_OFFLOAD_SERVER_NOT_ACCEPTING);
} else if (!bluetooth::shim::GetLppOffloadManager()->SocketOpened(socket_context)) {
log::warn("RFCOMM socket opened failed. Disconnect the incoming connection.");
- cleanup_rfc_slot(accept_rs);
+ cleanup_rfc_slot(accept_rs, BTSOCK_ERROR_OFFLOAD_HAL_OPEN_FAILURE);
} else {
log::info("RFCOMM socket opened successful. Will send connect signal in async callback.");
}
@@ -728,7 +733,9 @@ static uint32_t on_srv_rfc_connect(tBTA_JV_RFCOMM_SRV_OPEN* p_open, uint32_t id)
btif_sock_connection_logger(accept_rs->addr, accept_rs->id, BTSOCK_RFCOMM,
SOCKET_CONNECTION_STATE_CONNECTED,
accept_rs->f.server ? SOCKET_ROLE_LISTEN : SOCKET_ROLE_CONNECTION,
- accept_rs->app_uid, accept_rs->scn, 0, 0, accept_rs->service_name);
+ accept_rs->app_uid, accept_rs->scn, 0, 0, accept_rs->service_name, 0,
+ BTSOCK_ERROR_NONE, accept_rs->data_path);
+ accept_rs->connection_start_time_ms = common::time_gettimeofday_us() / 1000;
// Start monitoring the socket.
btsock_thread_add_fd(pth, srv_rs->fd, BTSOCK_RFCOMM, SOCK_THREAD_FD_EXCEPTION, srv_rs->id);
@@ -755,7 +762,8 @@ static void on_cli_rfc_connect_offload(tBTA_JV_RFCOMM_OPEN* p_open, rfc_slot_t*
btif_sock_connection_logger(
slot->addr, slot->id, BTSOCK_RFCOMM, SOCKET_CONNECTION_STATE_CONNECTED,
slot->f.server ? SOCKET_ROLE_LISTEN : SOCKET_ROLE_CONNECTION, slot->app_uid, slot->scn, 0,
- 0, slot->service_uuid.ToString().c_str());
+ 0, slot->service_uuid.ToString().c_str(), 0, BTSOCK_ERROR_NONE, slot->data_path);
+ slot->connection_start_time_ms = common::time_gettimeofday_us() / 1000;
bluetooth::hal::SocketContext socket_context = {
.socket_id = slot->socket_id,
@@ -770,7 +778,7 @@ static void on_cli_rfc_connect_offload(tBTA_JV_RFCOMM_OPEN* p_open, rfc_slot_t*
};
if (!bluetooth::shim::GetLppOffloadManager()->SocketOpened(socket_context)) {
log::warn("RFCOMM socket opened failed. Disconnect the incoming connection.");
- cleanup_rfc_slot(slot);
+ cleanup_rfc_slot(slot, BTSOCK_ERROR_OFFLOAD_HAL_OPEN_FAILURE);
} else {
log::info(
"RFCOMM socket opened successful. Will send connect signal in "
@@ -790,7 +798,7 @@ static void on_cli_rfc_connect(tBTA_JV_RFCOMM_OPEN* p_open, uint32_t id) {
if (p_open->status != tBTA_JV_STATUS::SUCCESS) {
log::warn("CONNECT unsuccessful, status {}. Cleaning up slot_id {}",
bta_jv_status_text(p_open->status), slot->id);
- cleanup_rfc_slot(slot);
+ cleanup_rfc_slot(slot, BTSOCK_ERROR_CONNECTION_FAILURE);
return;
}
@@ -811,7 +819,8 @@ static void on_cli_rfc_connect(tBTA_JV_RFCOMM_OPEN* p_open, uint32_t id) {
btif_sock_connection_logger(
slot->addr, slot->id, BTSOCK_RFCOMM, SOCKET_CONNECTION_STATE_CONNECTED,
slot->f.server ? SOCKET_ROLE_LISTEN : SOCKET_ROLE_CONNECTION, slot->app_uid, slot->scn, 0,
- 0, slot->service_uuid.ToString().c_str());
+ 0, slot->service_uuid.ToString().c_str(), 0, BTSOCK_ERROR_NONE, slot->data_path);
+ slot->connection_start_time_ms = common::time_gettimeofday_us() / 1000;
if (send_app_connect_signal(slot->fd, &slot->addr, slot->scn, 0, -1, slot->socket_id)) {
slot->f.connected = true;
@@ -847,7 +856,7 @@ void on_btsocket_rfc_opened_complete(uint64_t socket_id, bool success) {
}
if (!success) {
log::error("RFCOMM opened complete failed with socket_id: {}", socket_id);
- cleanup_rfc_slot(slot);
+ cleanup_rfc_slot(slot, BTSOCK_ERROR_OPEN_FAILURE);
return;
}
// If the socket was accepted from listen socket, use listen_fd.
@@ -877,7 +886,7 @@ void on_btsocket_rfc_close(uint64_t socket_id) {
return;
}
log::info("RFCOMM close request for socket_id: {}", socket_id);
- cleanup_rfc_slot(slot);
+ cleanup_rfc_slot(slot, BTSOCK_ERROR_NONE);
}
// TODO(b/380189525): Replace the randomized socket ID with static counter when we don't have
@@ -900,12 +909,13 @@ static void on_rfc_close(tBTA_JV_RFCOMM_CLOSE* /* p_close */, uint32_t id) {
log::warn("RFCOMM slot with id {} not found.", id);
return;
}
- log_socket_connection_state(slot->addr, slot->id, BTSOCK_RFCOMM,
- android::bluetooth::SOCKET_CONNECTION_STATE_DISCONNECTING, 0, 0,
- slot->app_uid, slot->scn,
- slot->f.server ? android::bluetooth::SOCKET_ROLE_LISTEN
- : android::bluetooth::SOCKET_ROLE_CONNECTION);
- cleanup_rfc_slot(slot);
+ bluetooth::shim::LogMetricSocketConnectionState(
+ slot->addr, slot->id, BTSOCK_RFCOMM,
+ android::bluetooth::SOCKET_CONNECTION_STATE_DISCONNECTING, 0, 0, slot->app_uid, slot->scn,
+ slot->f.server ? android::bluetooth::SOCKET_ROLE_LISTEN
+ : android::bluetooth::SOCKET_ROLE_CONNECTION,
+ 0, android::bluetooth::SOCKET_ERROR_NONE, slot->data_path);
+ cleanup_rfc_slot(slot, BTSOCK_ERROR_NONE);
}
static void on_rfc_write_done(tBTA_JV_RFCOMM_WRITE* p, uint32_t id) {
@@ -1010,7 +1020,7 @@ static void jv_dm_cback(tBTA_JV_EVT event, tBTA_JV* p_data, uint32_t id) {
if (p_data->scn == 0) {
log::error("Unable to allocate scn: all resources exhausted. slot found: {}",
std::format_ptr(rs));
- cleanup_rfc_slot(rs);
+ cleanup_rfc_slot(rs, BTSOCK_ERROR_SCN_ALLOCATION_FAILURE);
break;
}
@@ -1018,7 +1028,7 @@ static void jv_dm_cback(tBTA_JV_EVT event, tBTA_JV* p_data, uint32_t id) {
// Send channel ID to java layer
if (!send_app_scn(rs)) {
log::warn("send_app_scn() failed, closing rs->id:{}", rs->id);
- cleanup_rfc_slot(rs);
+ cleanup_rfc_slot(rs, BTSOCK_ERROR_SEND_SCN_FAILURE);
break;
}
@@ -1071,7 +1081,7 @@ static void jv_dm_cback(tBTA_JV_EVT event, tBTA_JV* p_data, uint32_t id) {
if (!create_server_sdp_record(slot)) {
log::error("cannot start server, slot found: {}", std::format_ptr(slot));
- cleanup_rfc_slot(slot);
+ cleanup_rfc_slot(slot, BTSOCK_ERROR_ADD_SDP_FAILURE);
break;
}
@@ -1137,7 +1147,7 @@ static void handle_discovery_comp(tBTA_JV_STATUS status, int scn, uint32_t id) {
id, bta_jv_status_text(status), scn);
bta_collect_rfc_metrics_after_sdp_fail(status, slot->addr, slot->app_uid, slot->security,
static_cast<bool>(slot->f.server), sdp_duration_ms);
- cleanup_rfc_slot(slot);
+ cleanup_rfc_slot(slot, BTSOCK_ERROR_SDP_DISCOVERY_FAILURE);
return;
}
@@ -1159,7 +1169,7 @@ static void handle_discovery_comp(tBTA_JV_STATUS status, int scn, uint32_t id) {
if (BTA_JvRfcommConnect(slot->security, scn, slot->addr, rfcomm_cback, slot->id, cfg,
slot->app_uid, sdp_duration_ms) != tBTA_JV_STATUS::SUCCESS) {
log::warn("BTA_JvRfcommConnect() returned BTA_JV_FAILURE for RFCOMM slot_id:{}", id);
- cleanup_rfc_slot(slot);
+ cleanup_rfc_slot(slot, BTSOCK_ERROR_CONNECTION_FAILURE);
return;
}
// Establish connection if successfully found channel number to connect.
@@ -1168,7 +1178,7 @@ static void handle_discovery_comp(tBTA_JV_STATUS status, int scn, uint32_t id) {
if (!send_app_scn(slot)) {
log::warn("send_app_scn() failed, closing slot_id {}", slot->id);
- cleanup_rfc_slot(slot);
+ cleanup_rfc_slot(slot, BTSOCK_ERROR_SEND_SCN_FAILURE);
return;
}
}
@@ -1276,6 +1286,7 @@ static bool btsock_rfc_read_signaled_on_listen_socket(int fd, int /* flags */, u
static void btsock_rfc_signaled_flagged(int fd, int flags, uint32_t id) {
bool need_close = false;
+ btsock_error_code_t error_code = BTSOCK_ERROR_NONE;
std::unique_lock<std::recursive_mutex> lock(slot_lock);
rfc_slot_t* slot = find_rfc_slot_by_id(id);
if (!slot) {
@@ -1289,11 +1300,13 @@ static void btsock_rfc_signaled_flagged(int fd, int flags, uint32_t id) {
// app sending data on connection socket
if (!btsock_rfc_read_signaled_on_connected_socket(fd, flags, id, slot)) {
need_close = true;
+ error_code = BTSOCK_ERROR_READ_SIGNALED_FAILURE;
}
} else {
// app sending signal on listen socket
if (!btsock_rfc_read_signaled_on_listen_socket(fd, flags, id, slot)) {
need_close = true;
+ error_code = BTSOCK_ERROR_READ_SIGNALED_FAILURE;
}
}
}
@@ -1306,6 +1319,7 @@ static void btsock_rfc_signaled_flagged(int fd, int flags, uint32_t id) {
"slot_id: {}, channel: {}",
slot->id, slot->scn);
need_close = true;
+ error_code = BTSOCK_ERROR_WRITE_SIGNALED_FAILURE;
}
}
@@ -1317,7 +1331,7 @@ static void btsock_rfc_signaled_flagged(int fd, int flags, uint32_t id) {
slot->f.doing_sdp_request) {
BTA_JvCancelDiscovery(slot->id);
}
- cleanup_rfc_slot(slot);
+ cleanup_rfc_slot(slot, error_code);
}
}
}
@@ -1328,6 +1342,7 @@ void btsock_rfc_signaled(int fd, int flags, uint32_t id) {
return;
}
bool need_close = false;
+ btsock_error_code_t error_code = BTSOCK_ERROR_NONE;
std::unique_lock<std::recursive_mutex> lock(slot_lock);
rfc_slot_t* slot = find_rfc_slot_by_id(id);
if (!slot) {
@@ -1346,6 +1361,7 @@ void btsock_rfc_signaled(int fd, int flags, uint32_t id) {
} else {
log::error("socket signaled for read while disconnected, slot_id: {}, channel: {}", slot->id,
slot->scn);
+ error_code = BTSOCK_ERROR_READ_SIGNALED_FAILURE;
need_close = true;
}
}
@@ -1357,6 +1373,7 @@ void btsock_rfc_signaled(int fd, int flags, uint32_t id) {
"socket signaled for write while disconnected (or write failure), "
"slot_id: {}, channel: {}",
slot->id, slot->scn);
+ error_code = BTSOCK_ERROR_WRITE_SIGNALED_FAILURE;
need_close = true;
}
}
@@ -1369,7 +1386,7 @@ void btsock_rfc_signaled(int fd, int flags, uint32_t id) {
slot->f.doing_sdp_request) {
BTA_JvCancelDiscovery(slot->id);
}
- cleanup_rfc_slot(slot);
+ cleanup_rfc_slot(slot, error_code);
}
}
}
@@ -1403,7 +1420,7 @@ int bta_co_rfc_data_incoming(uint32_t id, BT_HDR* p_buf) {
case SENT_FAILED:
osi_free(p_buf);
- cleanup_rfc_slot(slot);
+ cleanup_rfc_slot(slot, BTSOCK_ERROR_SEND_TO_APP_FAILURE);
break;
}
} else {
@@ -1428,7 +1445,7 @@ int bta_co_rfc_data_outgoing_size(uint32_t id, int* size) {
if (ioctl(slot->fd, FIONREAD, size) != 0) {
log::error("unable to determine bytes remaining to be read on fd {}: {}", slot->fd,
strerror(errno));
- cleanup_rfc_slot(slot);
+ cleanup_rfc_slot(slot, BTSOCK_ERROR_RECEIVE_DATA_FAILURE);
return false;
}
@@ -1448,7 +1465,7 @@ int bta_co_rfc_data_outgoing(uint32_t id, uint8_t* buf, uint16_t size) {
if (received != size) {
log::error("error receiving RFCOMM data from app: {}", strerror(errno));
- cleanup_rfc_slot(slot);
+ cleanup_rfc_slot(slot, BTSOCK_ERROR_RECEIVE_DATA_FAILURE);
return false;
}
@@ -1465,7 +1482,7 @@ bt_status_t btsock_rfc_disconnect(const RawAddress* bd_addr) {
std::unique_lock<std::recursive_mutex> lock(slot_lock);
for (size_t i = 0; i < ARRAY_SIZE(rfc_slots); ++i) {
if (rfc_slots[i].id && rfc_slots[i].addr == *bd_addr) {
- cleanup_rfc_slot(&rfc_slots[i]);
+ cleanup_rfc_slot(&rfc_slots[i], BTSOCK_ERROR_NONE);
}
}
diff --git a/system/btif/test/btif_core_test.cc b/system/btif/test/btif_core_test.cc
index 7342a17b99..3073bd194c 100644
--- a/system/btif/test/btif_core_test.cc
+++ b/system/btif/test/btif_core_test.cc
@@ -207,7 +207,8 @@ class BtifCoreTest : public ::testing::Test {
protected:
void SetUp() override {
callback_map_.clear();
- bluetooth::hci::testing::mock_controller_ = &controller_;
+ bluetooth::hci::testing::mock_controller_ =
+ std::make_unique<bluetooth::hci::testing::MockControllerInterface>();
bluetooth::testing::set_hal_cbacks(&callbacks);
auto promise = std::promise<void>();
auto future = promise.get_future();
@@ -223,17 +224,17 @@ protected:
callback_map_["callback_thread_event"] = [&promise]() { promise.set_value(); };
CleanCoreInterface();
ASSERT_EQ(std::future_status::ready, future.wait_for(timeout_time));
- bluetooth::hci::testing::mock_controller_ = nullptr;
+ bluetooth::hci::testing::mock_controller_.reset();
callback_map_.erase("callback_thread_event");
}
- bluetooth::hci::testing::MockControllerInterface controller_;
};
class BtifCoreWithControllerTest : public BtifCoreTest {
protected:
void SetUp() override {
BtifCoreTest::SetUp();
- ON_CALL(controller_, SupportsSniffSubrating).WillByDefault(Return(true));
+ ON_CALL(*bluetooth::hci::testing::mock_controller_, SupportsSniffSubrating)
+ .WillByDefault(Return(true));
}
void TearDown() override { BtifCoreTest::TearDown(); }
@@ -761,12 +762,13 @@ class BtifCoreWithVendorSupportTest : public BtifCoreWithControllerTest {
protected:
void SetUp() override {
BtifCoreWithControllerTest::SetUp();
- bluetooth::hci::testing::mock_hci_layer_ = &hci_;
+ bluetooth::hci::testing::mock_hci_layer_ =
+ std::make_unique<bluetooth::hci::testing::MockHciLayer>();
test::mock::osi_properties::osi_property_get.body = get_properties;
std::promise<void> configuration_promise;
auto configuration_done = configuration_promise.get_future();
- EXPECT_CALL(hci_,
+ EXPECT_CALL(*bluetooth::hci::testing::mock_hci_layer_,
EnqueueCommand(_, Matcher<ContextualOnceCallback<void(CommandCompleteView)>>(_)))
.WillOnce(
// Replace with real PDL for 0xfc17
@@ -784,7 +786,7 @@ protected:
configuration_promise.set_value();
})
.RetiresOnSaturation();
- EXPECT_CALL(hci_,
+ EXPECT_CALL(*bluetooth::hci::testing::mock_hci_layer_,
EnqueueCommand(_, Matcher<ContextualOnceCallback<void(CommandCompleteView)>>(_)))
.WillOnce([](std::unique_ptr<CommandBuilder> cmd,
ContextualOnceCallback<void(CommandCompleteView)> callback) {
@@ -798,7 +800,8 @@ protected:
callback(response);
})
.RetiresOnSaturation();
- EXPECT_CALL(hci_, RegisterVendorSpecificEventHandler(VseSubeventCode::BQR_EVENT, _))
+ EXPECT_CALL(*bluetooth::hci::testing::mock_hci_layer_,
+ RegisterVendorSpecificEventHandler(VseSubeventCode::BQR_EVENT, _))
.WillOnce(SaveArg<1>(&this->vse_callback_));
do_in_main_thread(BindOnce([]() { bluetooth::bqr::EnableBtQualityReport(get_main()); }));
ASSERT_EQ(std::future_status::ready, configuration_done.wait_for(std::chrono::seconds(1)));
@@ -808,18 +811,18 @@ protected:
std::promise<void> disable_promise;
auto disable_future = disable_promise.get_future();
auto set_promise = [&disable_promise]() { disable_promise.set_value(); };
- EXPECT_CALL(hci_, UnregisterVendorSpecificEventHandler(VseSubeventCode::BQR_EVENT));
- EXPECT_CALL(hci_,
+ EXPECT_CALL(*bluetooth::hci::testing::mock_hci_layer_,
+ UnregisterVendorSpecificEventHandler(VseSubeventCode::BQR_EVENT));
+ EXPECT_CALL(*bluetooth::hci::testing::mock_hci_layer_,
EnqueueCommand(_, Matcher<ContextualOnceCallback<void(CommandCompleteView)>>(_)))
.WillOnce(Invoke(set_promise))
.RetiresOnSaturation();
do_in_main_thread(BindOnce([]() { bluetooth::bqr::DisableBtQualityReport(); }));
ASSERT_EQ(std::future_status::ready, disable_future.wait_for(std::chrono::seconds(1)));
- bluetooth::hci::testing::mock_hci_layer_ = nullptr;
+ bluetooth::hci::testing::mock_hci_layer_.reset();
BtifCoreWithControllerTest::TearDown();
}
- bluetooth::hci::testing::MockHciLayer hci_;
ContextualCallback<void(VendorSpecificEventView)> vse_callback_;
};
diff --git a/system/common/Android.bp b/system/common/Android.bp
index 98e99e6d7b..c192613dbc 100644
--- a/system/common/Android.bp
+++ b/system/common/Android.bp
@@ -77,9 +77,7 @@ cc_test {
srcs: [
"address_obfuscator_unittest.cc",
"base_bind_unittest.cc",
- "id_generator_unittest.cc",
"leaky_bonded_queue_unittest.cc",
- "lru_unittest.cc",
"message_loop_thread_unittest.cc",
"repeating_timer_unittest.cc",
"state_machine_unittest.cc",
diff --git a/system/common/BUILD.gn b/system/common/BUILD.gn
index a1884973dd..50ec9c1dd0 100644
--- a/system/common/BUILD.gn
+++ b/system/common/BUILD.gn
@@ -30,7 +30,6 @@ static_library("common") {
include_dirs = [
"//bt/system/",
"//bt/system/stack/include",
- "//bt/system/linux_include",
]
deps = [
diff --git a/system/common/id_generator.h b/system/common/id_generator.h
deleted file mode 100644
index 7c6425aeef..0000000000
--- a/system/common/id_generator.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright 2019 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.
- */
-
-#pragma once
-
-#include <array>
-
-/* Helper class generating N unique ids, from 0 to N-1 */
-template <std::size_t N>
-class IdGenerator {
-public:
- static int ALL_USED;
-
- IdGenerator() : in_use_{} {}
-
- /* Returns next free id, or ALL_USED if no ids left */
- int GetNext() {
- for (std::size_t i = 0; i < N; i++) {
- if (!in_use_[i]) {
- in_use_[i] = true;
- return i;
- }
- }
- return ALL_USED;
- }
-
- /* Release given ID */
- void Release(int id) { in_use_[id] = false; }
-
-private:
- std::array<bool, N> in_use_;
-};
-
-template <std::size_t N>
-int IdGenerator<N>::ALL_USED = -1;
diff --git a/system/common/id_generator_unittest.cc b/system/common/id_generator_unittest.cc
deleted file mode 100644
index 7b090cf365..0000000000
--- a/system/common/id_generator_unittest.cc
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright 2019 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.
- */
-
-#include "common/id_generator.h"
-
-#include <gtest/gtest.h>
-
-TEST(IdGeneratorTest, sanity_test) {
- IdGenerator<5> generator;
- ASSERT_EQ(0, generator.GetNext());
- ASSERT_EQ(1, generator.GetNext());
- ASSERT_EQ(2, generator.GetNext());
- ASSERT_EQ(3, generator.GetNext());
- ASSERT_EQ(4, generator.GetNext());
- ASSERT_EQ(generator.ALL_USED, generator.GetNext());
-
- generator.Release(3);
- ASSERT_EQ(3, generator.GetNext());
-
- generator.Release(0);
- generator.Release(2);
- ASSERT_EQ(0, generator.GetNext());
- ASSERT_EQ(2, generator.GetNext());
-}
diff --git a/system/common/lru.h b/system/common/lru.h
deleted file mode 100644
index ca0a5a1c35..0000000000
--- a/system/common/lru.h
+++ /dev/null
@@ -1,187 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2020 Google, Inc.
- *
- * 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.
- *
- ******************************************************************************/
-
-#pragma once
-
-#include <bluetooth/log.h>
-
-#include <functional>
-#include <iterator>
-#include <list>
-#include <mutex>
-#include <optional>
-#include <thread>
-#include <unordered_map>
-
-namespace bluetooth {
-
-namespace common {
-
-template <typename K, typename V>
-class LegacyLruCache {
-public:
- using Node = std::pair<K, V>;
- /**
- * Constructor of the cache
- *
- * @param capacity maximum size of the cache
- * @param log_tag, keyword to put at the head of log.
- */
- LegacyLruCache(const size_t& capacity, const std::string& log_tag) : capacity_(capacity) {
- if (capacity_ == 0) {
- // don't allow invalid capacity
- log::fatal("{} unable to have 0 LRU Cache capacity", log_tag);
- }
- }
-
- // delete copy constructor
- LegacyLruCache(LegacyLruCache const&) = delete;
- LegacyLruCache& operator=(LegacyLruCache const&) = delete;
-
- ~LegacyLruCache() { Clear(); }
-
- /**
- * Clear the cache
- */
- void Clear() {
- std::lock_guard<std::recursive_mutex> lock(lru_mutex_);
- lru_map_.clear();
- node_list_.clear();
- }
-
- /**
- * Same as Get, but return an iterator to the accessed element
- *
- * Modifying the returned iterator does not warm up the cache
- *
- * @param key
- * @return pointer to the underlying value to allow in-place modification
- * nullptr when not found, will be invalidated when the key is evicted
- */
- V* Find(const K& key) {
- std::lock_guard<std::recursive_mutex> lock(lru_mutex_);
- auto map_iterator = lru_map_.find(key);
- if (map_iterator == lru_map_.end()) {
- return nullptr;
- }
- node_list_.splice(node_list_.begin(), node_list_, map_iterator->second);
- return &(map_iterator->second->second);
- }
-
- /**
- * Get the value of a key, and move the key to the head of cache, if there is
- * one
- *
- * @param key
- * @param value, output parameter of value of the key
- * @return true if the cache has the key
- */
- bool Get(const K& key, V* value) {
- log::assert_that(value != nullptr, "assert failed: value != nullptr");
- std::lock_guard<std::recursive_mutex> lock(lru_mutex_);
- auto value_ptr = Find(key);
- if (value_ptr == nullptr) {
- return false;
- }
- *value = *value_ptr;
- return true;
- }
-
- /**
- * Check if the cache has the input key, move the key to the head
- * if there is one
- *
- * @param key
- * @return true if the cache has the key
- */
- bool HasKey(const K& key) {
- std::lock_guard<std::recursive_mutex> lock(lru_mutex_);
- return Find(key) != nullptr;
- }
-
- /**
- * Put a key-value pair to the head of cache
- *
- * @param key
- * @param value
- * @return evicted node if tail value is popped, std::nullopt if no value
- * is popped. std::optional can be treated as a boolean as well
- */
- std::optional<Node> Put(const K& key, V value) {
- std::lock_guard<std::recursive_mutex> lock(lru_mutex_);
- auto value_ptr = Find(key);
- if (value_ptr != nullptr) {
- // hasKey() calls get(), therefore already move the node to the head
- *value_ptr = std::move(value);
- return std::nullopt;
- }
-
- // remove tail
- std::optional<Node> ret = std::nullopt;
- if (lru_map_.size() == capacity_) {
- lru_map_.erase(node_list_.back().first);
- ret = std::move(node_list_.back());
- node_list_.pop_back();
- }
- // insert to dummy next;
- node_list_.emplace_front(key, std::move(value));
- lru_map_.emplace(key, node_list_.begin());
- return ret;
- }
-
- /**
- * Delete a key from cache
- *
- * @param key
- * @return true if deleted successfully
- */
- bool Remove(const K& key) {
- std::lock_guard<std::recursive_mutex> lock(lru_mutex_);
- auto map_iterator = lru_map_.find(key);
- if (map_iterator == lru_map_.end()) {
- return false;
- }
-
- // remove from the list
- node_list_.erase(map_iterator->second);
-
- // delete key from map
- lru_map_.erase(map_iterator);
-
- return true;
- }
-
- /**
- * Return size of the cache
- *
- * @return size of the cache
- */
- int Size() const {
- std::lock_guard<std::recursive_mutex> lock(lru_mutex_);
- return lru_map_.size();
- }
-
-private:
- std::list<Node> node_list_;
- size_t capacity_;
- std::unordered_map<K, typename std::list<Node>::iterator> lru_map_;
- mutable std::recursive_mutex lru_mutex_;
-};
-
-} // namespace common
-} // namespace bluetooth
diff --git a/system/common/lru_unittest.cc b/system/common/lru_unittest.cc
deleted file mode 100644
index 7b41143ec5..0000000000
--- a/system/common/lru_unittest.cc
+++ /dev/null
@@ -1,250 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2020 Google, Inc.
- *
- * 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.
- *
- ******************************************************************************/
-
-#include "common/lru.h"
-
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-
-#include <chrono>
-#include <limits>
-
-namespace testing {
-
-using bluetooth::common::LegacyLruCache;
-
-TEST(BluetoothLegacyLruCacheTest, LegacyLruCacheMainTest1) {
- int* value = new int(0);
- LegacyLruCache<int, int> cache(3, "testing"); // capacity = 3;
- cache.Put(1, 10);
- EXPECT_EQ(cache.Size(), 1);
- EXPECT_FALSE(cache.Put(2, 20));
- EXPECT_FALSE(cache.Put(3, 30));
- EXPECT_EQ(cache.Size(), 3);
-
- // 1, 2, 3 should be in cache
- EXPECT_TRUE(cache.Get(1, value));
- EXPECT_EQ(*value, 10);
- EXPECT_TRUE(cache.Get(2, value));
- EXPECT_EQ(*value, 20);
- EXPECT_TRUE(cache.Get(3, value));
- EXPECT_EQ(*value, 30);
- EXPECT_EQ(cache.Size(), 3);
-
- EXPECT_THAT(cache.Put(4, 40), Optional(Pair(1, 10)));
- // 2, 3, 4 should be in cache, 1 is evicted
- EXPECT_FALSE(cache.Get(1, value));
- EXPECT_TRUE(cache.Get(4, value));
- EXPECT_EQ(*value, 40);
- EXPECT_TRUE(cache.Get(2, value));
- EXPECT_EQ(*value, 20);
- EXPECT_TRUE(cache.Get(3, value));
- EXPECT_EQ(*value, 30);
-
- EXPECT_THAT(cache.Put(5, 50), Optional(Pair(4, 40)));
- EXPECT_EQ(cache.Size(), 3);
- // 2, 3, 5 should be in cache, 4 is evicted
-
- EXPECT_TRUE(cache.Remove(3));
- EXPECT_FALSE(cache.Put(6, 60));
- // 2, 5, 6 should be in cache
-
- EXPECT_FALSE(cache.Get(3, value));
- EXPECT_FALSE(cache.Get(4, value));
- EXPECT_TRUE(cache.Get(2, value));
- EXPECT_EQ(*value, 20);
- EXPECT_TRUE(cache.Get(5, value));
- EXPECT_EQ(*value, 50);
- EXPECT_TRUE(cache.Get(6, value));
- EXPECT_EQ(*value, 60);
-}
-
-TEST(BluetoothLegacyLruCacheTest, LegacyLruCacheMainTest2) {
- int* value = new int(0);
- LegacyLruCache<int, int> cache(2, "testing"); // size = 2;
- EXPECT_FALSE(cache.Put(1, 10));
- EXPECT_FALSE(cache.Put(2, 20));
- EXPECT_THAT(cache.Put(3, 30), Optional(Pair(1, 10)));
- EXPECT_FALSE(cache.Put(2, 200));
- EXPECT_EQ(cache.Size(), 2);
- // 3, 2 should be in cache
-
- EXPECT_FALSE(cache.HasKey(1));
- EXPECT_TRUE(cache.Get(2, value));
- EXPECT_EQ(*value, 200);
- EXPECT_TRUE(cache.Get(3, value));
- EXPECT_EQ(*value, 30);
-
- EXPECT_THAT(cache.Put(4, 40), Optional(Pair(2, 200)));
- // 3, 4 should be in cache
-
- EXPECT_FALSE(cache.HasKey(2));
- EXPECT_TRUE(cache.Get(3, value));
- EXPECT_EQ(*value, 30);
- EXPECT_TRUE(cache.Get(4, value));
- EXPECT_EQ(*value, 40);
-
- EXPECT_TRUE(cache.Remove(4));
- EXPECT_EQ(cache.Size(), 1);
- cache.Put(2, 2000);
- // 3, 2 should be in cache
-
- EXPECT_FALSE(cache.HasKey(4));
- EXPECT_TRUE(cache.Get(3, value));
- EXPECT_EQ(*value, 30);
- EXPECT_TRUE(cache.Get(2, value));
- EXPECT_EQ(*value, 2000);
-
- EXPECT_TRUE(cache.Remove(2));
- EXPECT_TRUE(cache.Remove(3));
- cache.Put(5, 50);
- cache.Put(1, 100);
- cache.Put(1, 1000);
- EXPECT_EQ(cache.Size(), 2);
- // 1, 5 should be in cache
-
- EXPECT_FALSE(cache.HasKey(2));
- EXPECT_FALSE(cache.HasKey(3));
- EXPECT_TRUE(cache.Get(1, value));
- EXPECT_EQ(*value, 1000);
- EXPECT_TRUE(cache.Get(5, value));
- EXPECT_EQ(*value, 50);
-}
-
-TEST(BluetoothLegacyLruCacheTest, LegacyLruCacheFindTest) {
- LegacyLruCache<int, int> cache(10, "testing");
- cache.Put(1, 10);
- cache.Put(2, 20);
- int value = 0;
- EXPECT_TRUE(cache.Get(1, &value));
- EXPECT_EQ(value, 10);
- auto value_ptr = cache.Find(1);
- EXPECT_NE(value_ptr, nullptr);
- *value_ptr = 20;
- EXPECT_TRUE(cache.Get(1, &value));
- EXPECT_EQ(value, 20);
- cache.Put(1, 40);
- EXPECT_EQ(*value_ptr, 40);
- EXPECT_EQ(cache.Find(10), nullptr);
-}
-
-TEST(BluetoothLegacyLruCacheTest, LegacyLruCacheGetTest) {
- LegacyLruCache<int, int> cache(10, "testing");
- cache.Put(1, 10);
- cache.Put(2, 20);
- int value = 0;
- EXPECT_TRUE(cache.Get(1, &value));
- EXPECT_EQ(value, 10);
- EXPECT_TRUE(cache.HasKey(1));
- EXPECT_TRUE(cache.HasKey(2));
- EXPECT_FALSE(cache.HasKey(3));
- EXPECT_FALSE(cache.Get(3, &value));
- EXPECT_EQ(value, 10);
-}
-
-TEST(BluetoothLegacyLruCacheTest, LegacyLruCacheRemoveTest) {
- LegacyLruCache<int, int> cache(10, "testing");
- for (int key = 0; key <= 30; key++) {
- cache.Put(key, key * 100);
- }
- for (int key = 0; key <= 20; key++) {
- EXPECT_FALSE(cache.HasKey(key));
- }
- for (int key = 21; key <= 30; key++) {
- EXPECT_TRUE(cache.HasKey(key));
- }
- for (int key = 21; key <= 30; key++) {
- EXPECT_TRUE(cache.Remove(key));
- }
- for (int key = 21; key <= 30; key++) {
- EXPECT_FALSE(cache.HasKey(key));
- }
-}
-
-TEST(BluetoothLegacyLruCacheTest, LegacyLruCacheClearTest) {
- LegacyLruCache<int, int> cache(10, "testing");
- for (int key = 0; key < 10; key++) {
- cache.Put(key, key * 100);
- }
- for (int key = 0; key < 10; key++) {
- EXPECT_TRUE(cache.HasKey(key));
- }
- cache.Clear();
- for (int key = 0; key < 10; key++) {
- EXPECT_FALSE(cache.HasKey(key));
- }
-
- for (int key = 0; key < 10; key++) {
- cache.Put(key, key * 1000);
- }
- for (int key = 0; key < 10; key++) {
- EXPECT_TRUE(cache.HasKey(key));
- }
-}
-
-TEST(BluetoothLegacyLruCacheTest, LegacyLruCachePressureTest) {
- int max_size = 0xFFFFF; // 2^20 = 1M
- LegacyLruCache<int, int> cache(static_cast<size_t>(max_size), "testing");
-
- // fill the cache
- for (int key = 0; key < max_size; key++) {
- cache.Put(key, key);
- }
-
- // make sure the cache is full
- for (int key = 0; key < max_size; key++) {
- EXPECT_TRUE(cache.HasKey(key));
- }
-
- // refresh the entire cache
- for (int key = 0; key < max_size; key++) {
- int new_key = key + max_size;
- cache.Put(new_key, new_key);
- EXPECT_FALSE(cache.HasKey(key));
- EXPECT_TRUE(cache.HasKey(new_key));
- }
-
- // clear the entire cache
- int* value = new int(0);
- for (int key = max_size; key < 2 * max_size; key++) {
- EXPECT_TRUE(cache.Get(key, value));
- EXPECT_EQ(*value, key);
- EXPECT_TRUE(cache.Remove(key));
- }
- EXPECT_EQ(cache.Size(), 0);
-}
-
-TEST(BluetoothLegacyLruCacheTest, BluetoothLruMultiThreadPressureTest) {
- LegacyLruCache<int, int> cache(100, "testing");
- auto pointer = &cache;
- // make sure no deadlock
- std::vector<std::thread> workers;
- for (int key = 0; key < 100; key++) {
- workers.push_back(std::thread([key, pointer]() {
- pointer->Put(key, key);
- EXPECT_TRUE(pointer->HasKey(key));
- EXPECT_TRUE(pointer->Remove(key));
- }));
- }
- for (auto& worker : workers) {
- worker.join();
- }
- EXPECT_EQ(cache.Size(), 0);
-}
-
-} // namespace testing
diff --git a/system/common/metrics.cc b/system/common/metrics.cc
index 45b11acf46..c6c0977115 100644
--- a/system/common/metrics.cc
+++ b/system/common/metrics.cc
@@ -18,84 +18,19 @@
#include "common/metrics.h"
-#include <base/base64.h>
#include <bluetooth/log.h>
#include <frameworks/proto_logging/stats/enums/bluetooth/le/enums.pb.h>
-#include <include/hardware/bt_av.h>
#include <statslog_bt.h>
-#include <unistd.h>
-#include <algorithm>
-#include <cerrno>
#include <cstdint>
-#include <cstring>
-#include <memory>
-#include <mutex> // NOLINT
-#include <utility>
+#include <vector>
-#include "common/address_obfuscator.h"
-#include "common/leaky_bonded_queue.h"
-#include "common/time_util.h"
-#include "hci/address.h"
#include "main/shim/metric_id_api.h"
-#include "osi/include/osi.h"
#include "types/raw_address.h"
-namespace std {
-template <>
-struct formatter<android::bluetooth::DirectionEnum>
- : enum_formatter<android::bluetooth::DirectionEnum> {};
-template <>
-struct formatter<android::bluetooth::SocketConnectionstateEnum>
- : enum_formatter<android::bluetooth::SocketConnectionstateEnum> {};
-template <>
-struct formatter<android::bluetooth::SocketRoleEnum>
- : enum_formatter<android::bluetooth::SocketRoleEnum> {};
-template <>
-struct formatter<android::bluetooth::AddressTypeEnum>
- : enum_formatter<android::bluetooth::AddressTypeEnum> {};
-template <>
-struct formatter<android::bluetooth::DeviceInfoSrcEnum>
- : enum_formatter<android::bluetooth::DeviceInfoSrcEnum> {};
-} // namespace std
-
namespace bluetooth {
namespace common {
-using bluetooth::hci::Address;
-
-void LogLinkLayerConnectionEvent(const RawAddress* address, uint32_t connection_handle,
- android::bluetooth::DirectionEnum direction, uint16_t link_type,
- uint32_t hci_cmd, uint16_t hci_event, uint16_t hci_ble_event,
- uint16_t cmd_status, uint16_t reason_code) {
- std::string obfuscated_id;
- int metric_id = 0;
- if (address != nullptr) {
- obfuscated_id = AddressObfuscator::GetInstance()->Obfuscate(*address);
- metric_id = bluetooth::shim::AllocateIdFromMetricIdAllocator(*address);
- }
- // nullptr and size 0 represent missing value for obfuscated_id
- BytesField bytes_field(address != nullptr ? obfuscated_id.c_str() : nullptr,
- address != nullptr ? obfuscated_id.size() : 0);
- int ret = stats_write(BLUETOOTH_LINK_LAYER_CONNECTION_EVENT, bytes_field, connection_handle,
- direction, link_type, hci_cmd, hci_event, hci_ble_event, cmd_status,
- reason_code, metric_id);
- if (ret < 0) {
- log::warn(
- "failed to log status 0x{:x}, reason 0x{:x} from cmd 0x{:x}, event "
- "0x{:x}, ble_event 0x{:x} for {}, handle {}, type 0x{:x}, error {}",
- cmd_status, reason_code, hci_cmd, hci_event, hci_ble_event, *address, connection_handle,
- link_type, ret);
- }
-}
-
-void LogHciTimeoutEvent(uint32_t hci_cmd) {
- int ret = stats_write(BLUETOOTH_HCI_TIMEOUT_REPORTED, static_cast<int64_t>(hci_cmd));
- if (ret < 0) {
- log::warn("failed for opcode 0x{:x}, error {}", hci_cmd, ret);
- }
-}
-
void LogRemoteVersionInfo(uint16_t handle, uint8_t status, uint8_t version,
uint16_t manufacturer_name, uint16_t subversion) {
int ret = stats_write(BLUETOOTH_REMOTE_VERSION_INFO_REPORTED, handle, status, version,
@@ -108,271 +43,6 @@ void LogRemoteVersionInfo(uint16_t handle, uint8_t status, uint8_t version,
}
}
-void LogA2dpAudioUnderrunEvent(const RawAddress& address, uint64_t encoding_interval_millis,
- int num_missing_pcm_bytes) {
- std::string obfuscated_id;
- int metric_id = 0;
- if (!address.IsEmpty()) {
- obfuscated_id = AddressObfuscator::GetInstance()->Obfuscate(address);
- metric_id = bluetooth::shim::AllocateIdFromMetricIdAllocator(address);
- }
- // nullptr and size 0 represent missing value for obfuscated_id
- BytesField bytes_field(address.IsEmpty() ? nullptr : obfuscated_id.c_str(),
- address.IsEmpty() ? 0 : obfuscated_id.size());
- int64_t encoding_interval_nanos = encoding_interval_millis * 1000000;
- int ret = stats_write(BLUETOOTH_A2DP_AUDIO_UNDERRUN_REPORTED, bytes_field,
- encoding_interval_nanos, num_missing_pcm_bytes, metric_id);
- if (ret < 0) {
- log::warn(
- "failed for {}, encoding_interval_nanos {}, num_missing_pcm_bytes {}, "
- "error {}",
- address, encoding_interval_nanos, num_missing_pcm_bytes, ret);
- }
-}
-
-void LogA2dpAudioOverrunEvent(const RawAddress& address, uint64_t encoding_interval_millis,
- int num_dropped_buffers, int num_dropped_encoded_frames,
- int num_dropped_encoded_bytes) {
- std::string obfuscated_id;
- int metric_id = 0;
- if (!address.IsEmpty()) {
- obfuscated_id = AddressObfuscator::GetInstance()->Obfuscate(address);
- metric_id = bluetooth::shim::AllocateIdFromMetricIdAllocator(address);
- }
- // nullptr and size 0 represent missing value for obfuscated_id
- BytesField bytes_field(address.IsEmpty() ? nullptr : obfuscated_id.c_str(),
- address.IsEmpty() ? 0 : obfuscated_id.size());
- int64_t encoding_interval_nanos = encoding_interval_millis * 1000000;
- int ret = stats_write(BLUETOOTH_A2DP_AUDIO_OVERRUN_REPORTED, bytes_field, encoding_interval_nanos,
- num_dropped_buffers, num_dropped_encoded_frames, num_dropped_encoded_bytes,
- metric_id);
- if (ret < 0) {
- log::warn(
- "failed to log for {}, encoding_interval_nanos {}, num_dropped_buffers "
- "{}, num_dropped_encoded_frames {}, num_dropped_encoded_bytes {}, "
- "error {}",
- address, encoding_interval_nanos, num_dropped_buffers, num_dropped_encoded_frames,
- num_dropped_encoded_bytes, ret);
- }
-}
-
-void LogA2dpPlaybackEvent(const RawAddress& address, int playback_state, int audio_coding_mode) {
- std::string obfuscated_id;
- int metric_id = 0;
- if (!address.IsEmpty()) {
- obfuscated_id = AddressObfuscator::GetInstance()->Obfuscate(address);
- metric_id = bluetooth::shim::AllocateIdFromMetricIdAllocator(address);
- }
- // nullptr and size 0 represent missing value for obfuscated_id
- BytesField bytes_field(address.IsEmpty() ? nullptr : obfuscated_id.c_str(),
- address.IsEmpty() ? 0 : obfuscated_id.size());
- int ret = stats_write(BLUETOOTH_A2DP_PLAYBACK_STATE_CHANGED, bytes_field, playback_state,
- audio_coding_mode, metric_id);
- if (ret < 0) {
- log::warn(
- "failed to log for {}, playback_state {}, audio_coding_mode {}, error "
- "{}",
- address, playback_state, audio_coding_mode, ret);
- }
-}
-
-void LogReadRssiResult(const RawAddress& address, uint16_t handle, uint32_t cmd_status,
- int8_t rssi) {
- std::string obfuscated_id;
- int metric_id = 0;
- if (!address.IsEmpty()) {
- obfuscated_id = AddressObfuscator::GetInstance()->Obfuscate(address);
- metric_id = bluetooth::shim::AllocateIdFromMetricIdAllocator(address);
- }
- // nullptr and size 0 represent missing value for obfuscated_id
- BytesField bytes_field(address.IsEmpty() ? nullptr : obfuscated_id.c_str(),
- address.IsEmpty() ? 0 : obfuscated_id.size());
- int ret = stats_write(BLUETOOTH_DEVICE_RSSI_REPORTED, bytes_field, handle, cmd_status, rssi,
- metric_id);
- if (ret < 0) {
- log::warn("failed for {}, handle {}, status 0x{:x}, rssi {} dBm, error {}", address, handle,
- cmd_status, rssi, ret);
- }
-}
-
-void LogReadFailedContactCounterResult(const RawAddress& address, uint16_t handle,
- uint32_t cmd_status, int32_t failed_contact_counter) {
- std::string obfuscated_id;
- int metric_id = 0;
- if (!address.IsEmpty()) {
- obfuscated_id = AddressObfuscator::GetInstance()->Obfuscate(address);
- metric_id = bluetooth::shim::AllocateIdFromMetricIdAllocator(address);
- }
- // nullptr and size 0 represent missing value for obfuscated_id
- BytesField bytes_field(address.IsEmpty() ? nullptr : obfuscated_id.c_str(),
- address.IsEmpty() ? 0 : obfuscated_id.size());
- int ret = stats_write(BLUETOOTH_DEVICE_FAILED_CONTACT_COUNTER_REPORTED, bytes_field, handle,
- cmd_status, failed_contact_counter, metric_id);
- if (ret < 0) {
- log::warn(
- "failed for {}, handle {}, status 0x{:x}, failed_contact_counter {} "
- "packets, error {}",
- address, handle, cmd_status, failed_contact_counter, ret);
- }
-}
-
-void LogReadTxPowerLevelResult(const RawAddress& address, uint16_t handle, uint32_t cmd_status,
- int32_t transmit_power_level) {
- std::string obfuscated_id;
- int metric_id = 0;
- if (!address.IsEmpty()) {
- obfuscated_id = AddressObfuscator::GetInstance()->Obfuscate(address);
- metric_id = bluetooth::shim::AllocateIdFromMetricIdAllocator(address);
- }
- // nullptr and size 0 represent missing value for obfuscated_id
- BytesField bytes_field(address.IsEmpty() ? nullptr : obfuscated_id.c_str(),
- address.IsEmpty() ? 0 : obfuscated_id.size());
- int ret = stats_write(BLUETOOTH_DEVICE_TX_POWER_LEVEL_REPORTED, bytes_field, handle, cmd_status,
- transmit_power_level, metric_id);
- if (ret < 0) {
- log::warn(
- "failed for {}, handle {}, status 0x{:x}, transmit_power_level {} "
- "packets, error {}",
- address, handle, cmd_status, transmit_power_level, ret);
- }
-}
-
-void LogSmpPairingEvent(const RawAddress& address, uint8_t smp_cmd,
- android::bluetooth::DirectionEnum direction, uint8_t smp_fail_reason) {
- std::string obfuscated_id;
- int metric_id = 0;
- if (!address.IsEmpty()) {
- obfuscated_id = AddressObfuscator::GetInstance()->Obfuscate(address);
- metric_id = bluetooth::shim::AllocateIdFromMetricIdAllocator(address);
- }
- // nullptr and size 0 represent missing value for obfuscated_id
- BytesField obfuscated_id_field(address.IsEmpty() ? nullptr : obfuscated_id.c_str(),
- address.IsEmpty() ? 0 : obfuscated_id.size());
- int ret = stats_write(BLUETOOTH_SMP_PAIRING_EVENT_REPORTED, obfuscated_id_field, smp_cmd,
- direction, smp_fail_reason, metric_id);
- if (ret < 0) {
- log::warn(
- "failed for {}, smp_cmd 0x{:x}, direction {}, smp_fail_reason 0x{:x}, "
- "error {}",
- address, smp_cmd, direction, smp_fail_reason, ret);
- }
-}
-
-void LogClassicPairingEvent(const RawAddress& address, uint16_t handle, uint32_t hci_cmd,
- uint16_t hci_event, uint16_t cmd_status, uint16_t reason_code,
- int64_t event_value) {
- std::string obfuscated_id;
- int metric_id = 0;
- if (!address.IsEmpty()) {
- obfuscated_id = AddressObfuscator::GetInstance()->Obfuscate(address);
- metric_id = bluetooth::shim::AllocateIdFromMetricIdAllocator(address);
- }
- // nullptr and size 0 represent missing value for obfuscated_id
- BytesField obfuscated_id_field(address.IsEmpty() ? nullptr : obfuscated_id.c_str(),
- address.IsEmpty() ? 0 : obfuscated_id.size());
- int ret = stats_write(BLUETOOTH_CLASSIC_PAIRING_EVENT_REPORTED, obfuscated_id_field, handle,
- hci_cmd, hci_event, cmd_status, reason_code, event_value, metric_id);
- if (ret < 0) {
- log::warn(
- "failed for {}, handle {}, hci_cmd 0x{:x}, hci_event 0x{:x}, "
- "cmd_status 0x{:x}, reason 0x{:x}, event_value {}, error {}",
- address, handle, hci_cmd, hci_event, cmd_status, reason_code, event_value, ret);
- }
-}
-
-void LogSdpAttribute(const RawAddress& address, uint16_t protocol_uuid, uint16_t attribute_id,
- size_t attribute_size, const char* attribute_value) {
- std::string obfuscated_id;
- int metric_id = 0;
- if (!address.IsEmpty()) {
- obfuscated_id = AddressObfuscator::GetInstance()->Obfuscate(address);
- metric_id = bluetooth::shim::AllocateIdFromMetricIdAllocator(address);
- }
- // nullptr and size 0 represent missing value for obfuscated_id
- BytesField obfuscated_id_field(address.IsEmpty() ? nullptr : obfuscated_id.c_str(),
- address.IsEmpty() ? 0 : obfuscated_id.size());
- BytesField attribute_field(attribute_value, attribute_size);
- int ret = stats_write(BLUETOOTH_SDP_ATTRIBUTE_REPORTED, obfuscated_id_field, protocol_uuid,
- attribute_id, attribute_field, metric_id);
- if (ret < 0) {
- log::warn("failed for {}, protocol_uuid 0x{:x}, attribute_id 0x{:x}, error {}", address,
- protocol_uuid, attribute_id, ret);
- }
-}
-
-void LogSocketConnectionState(const RawAddress& address, int port, int type,
- android::bluetooth::SocketConnectionstateEnum connection_state,
- int64_t tx_bytes, int64_t rx_bytes, int uid, int server_port,
- android::bluetooth::SocketRoleEnum socket_role) {
- std::string obfuscated_id;
- int metric_id = 0;
- if (!address.IsEmpty()) {
- obfuscated_id = AddressObfuscator::GetInstance()->Obfuscate(address);
- metric_id = bluetooth::shim::AllocateIdFromMetricIdAllocator(address);
- }
- // nullptr and size 0 represent missing value for obfuscated_id
- BytesField obfuscated_id_field(address.IsEmpty() ? nullptr : obfuscated_id.c_str(),
- address.IsEmpty() ? 0 : obfuscated_id.size());
- int ret = stats_write(BLUETOOTH_SOCKET_CONNECTION_STATE_CHANGED, obfuscated_id_field, port, type,
- connection_state, tx_bytes, rx_bytes, uid, server_port, socket_role,
- metric_id, 0 /* connection_duration_ms */, 1 /* error_code */,
- 0 /* is_hardware_offload */);
- if (ret < 0) {
- log::warn(
- "failed for {}, port {}, type {}, state {}, tx_bytes {}, rx_bytes {}, "
- "uid {}, server_port {}, socket_role {}, error {}",
- address, port, type, connection_state, tx_bytes, rx_bytes, uid, server_port,
- socket_role, ret);
- }
-}
-
-void LogManufacturerInfo(const RawAddress& address,
- android::bluetooth::AddressTypeEnum address_type,
- android::bluetooth::DeviceInfoSrcEnum source_type,
- const std::string& source_name, const std::string& manufacturer,
- const std::string& model, const std::string& hardware_version,
- const std::string& software_version) {
- std::string obfuscated_id;
- int metric_id = 0;
- if (!address.IsEmpty()) {
- obfuscated_id = AddressObfuscator::GetInstance()->Obfuscate(address);
- metric_id = bluetooth::shim::AllocateIdFromMetricIdAllocator(address);
- }
- // nullptr and size 0 represent missing value for obfuscated_id
- BytesField obfuscated_id_field(address.IsEmpty() ? nullptr : obfuscated_id.c_str(),
- address.IsEmpty() ? 0 : obfuscated_id.size());
- int ret = stats_write(BLUETOOTH_DEVICE_INFO_REPORTED, obfuscated_id_field, source_type,
- source_name.c_str(), manufacturer.c_str(), model.c_str(),
- hardware_version.c_str(), software_version.c_str(), metric_id, address_type,
- address.address[5], address.address[4], address.address[3]);
- if (ret < 0) {
- log::warn(
- "failed for {}, source_type {}, source_name {}, manufacturer {}, model "
- "{}, hardware_version {}, software_version {} MAC address type {} MAC "
- "address prefix {} {} {}, error {}",
- address, source_type, source_name, manufacturer, model, hardware_version,
- software_version, address_type, address.address[5], address.address[4],
- address.address[3], ret);
- }
-}
-
-void LogBluetoothHalCrashReason(const RawAddress& address, uint32_t error_code,
- uint32_t vendor_error_code) {
- std::string obfuscated_id;
- if (!address.IsEmpty()) {
- obfuscated_id = AddressObfuscator::GetInstance()->Obfuscate(address);
- }
- // nullptr and size 0 represent missing value for obfuscated_id
- BytesField obfuscated_id_field(address.IsEmpty() ? nullptr : obfuscated_id.c_str(),
- address.IsEmpty() ? 0 : obfuscated_id.size());
- int ret = stats_write(BLUETOOTH_HAL_CRASH_REASON_REPORTED, 0, obfuscated_id_field, error_code,
- vendor_error_code);
- if (ret < 0) {
- log::warn("failed for {}, error_code 0x{:x}, vendor_error_code 0x{:x}, error {}", address,
- error_code, vendor_error_code, ret);
- }
-}
-
void LogLeAudioConnectionSessionReported(
int32_t group_size, int32_t group_metric_id, int64_t connection_duration_nanos,
const std::vector<int64_t>& device_connecting_offset_nanos,
@@ -421,5 +91,4 @@ void LogLeAudioBroadcastSessionReported(int64_t duration_nanos) {
}
} // namespace common
-
} // namespace bluetooth
diff --git a/system/common/metrics.h b/system/common/metrics.h
index 0aad20819e..4d5a234ce5 100644
--- a/system/common/metrics.h
+++ b/system/common/metrics.h
@@ -18,22 +18,12 @@
#pragma once
-#include <bta/include/bta_api.h>
-#include <frameworks/proto_logging/stats/enums/bluetooth/enums.pb.h>
-#include <frameworks/proto_logging/stats/enums/bluetooth/hci/enums.pb.h>
-#include <frameworks/proto_logging/stats/enums/bluetooth/le/enums.pb.h>
-#include <stdint.h>
-
-#include <memory>
-#include <string>
+#include <cstdint>
#include <vector>
-#include "hci/address.h"
-#include "os/metrics.h"
#include "types/raw_address.h"
namespace bluetooth {
-
namespace common {
/**
@@ -42,34 +32,6 @@ namespace common {
static const uint32_t kUnknownConnectionHandle = 0xFFFF;
/**
- * Log link layer connection event
- *
- * @param address Stack wide consistent Bluetooth address of this event,
- * nullptr if unknown
- * @param connection_handle connection handle of this event,
- * {@link kUnknownConnectionHandle} if unknown
- * @param direction direction of this connection
- * @param link_type type of the link
- * @param hci_cmd HCI command opecode associated with this event, if any
- * @param hci_event HCI event code associated with this event, if any
- * @param hci_ble_event HCI BLE event code associated with this event, if any
- * @param cmd_status Command status associated with this event, if any
- * @param reason_code Reason code associated with this event, if any
- */
-void LogLinkLayerConnectionEvent(const RawAddress* address, uint32_t connection_handle,
- android::bluetooth::DirectionEnum direction, uint16_t link_type,
- uint32_t hci_cmd, uint16_t hci_event, uint16_t hci_ble_event,
- uint16_t cmd_status, uint16_t reason_code);
-
-/**
- * Logs when Bluetooth controller failed to reply with command status within
- * a timeout period after receiving an HCI command from the host
- *
- * @param hci_cmd opcode of HCI command that caused this timeout
- */
-void LogHciTimeoutEvent(uint32_t hci_cmd);
-
-/**
* Logs when we receive Bluetooth Read Remote Version Information Complete
* Event from the remote device, as documented by the Bluetooth Core HCI
* specification
@@ -86,167 +48,6 @@ void LogHciTimeoutEvent(uint32_t hci_cmd);
void LogRemoteVersionInfo(uint16_t handle, uint8_t status, uint8_t version,
uint16_t manufacturer_name, uint16_t subversion);
-/**
- * Log A2DP audio buffer underrun event
- *
- * @param address A2DP device associated with this event
- * @param encoding_interval_millis encoding interval in milliseconds
- * @param num_missing_pcm_bytes number of PCM bytes that cannot be read from
- * the source
- */
-void LogA2dpAudioUnderrunEvent(const RawAddress& address, uint64_t encoding_interval_millis,
- int num_missing_pcm_bytes);
-
-/**
- * Log A2DP audio buffer overrun event
- *
- * @param address A2DP device associated with this event
- * @param encoding_interval_millis encoding interval in milliseconds
- * @param num_dropped_buffers number of encoded buffers dropped from Tx queue
- * @param num_dropped_encoded_frames number of encoded frames dropped from Tx
- * queue
- * @param num_dropped_encoded_bytes number of encoded bytes dropped from Tx
- * queue
- */
-void LogA2dpAudioOverrunEvent(const RawAddress& address, uint64_t encoding_interval_millis,
- int num_dropped_buffers, int num_dropped_encoded_frames,
- int num_dropped_encoded_bytes);
-
-/**
- * Log A2DP playback state changed event
- *
- * @param address A2DP device associated with this event
- * @param playback_state audio playback state
- * @param audio_coding_mode audio codec encoding mode
- */
-void LogA2dpPlaybackEvent(const RawAddress& address, int playback_state, int audio_coding_mode);
-
-/**
- * Log read RSSI result
- *
- * @param address device associated with this event
- * @param handle connection handle of this event,
- * {@link kUnknownConnectionHandle} if unknown
- * @param cmd_status command status from read RSSI command
- * @param rssi rssi value in dBm
- */
-void LogReadRssiResult(const RawAddress& address, uint16_t handle, uint32_t cmd_status,
- int8_t rssi);
-
-/**
- * Log failed contact counter report
- *
- * @param address device associated with this event
- * @param handle connection handle of this event,
- * {@link kUnknownConnectionHandle} if unknown
- * @param cmd_status command status from read failed contact counter command
- * @param failed_contact_counter Number of consecutive failed contacts for a
- * connection corresponding to the Handle
- */
-void LogReadFailedContactCounterResult(const RawAddress& address, uint16_t handle,
- uint32_t cmd_status, int32_t failed_contact_counter);
-
-/**
- * Log transmit power level for a particular device after read
- *
- * @param address device associated with this event
- * @param handle connection handle of this event,
- * {@link kUnknownConnectionHandle} if unknown
- * @param cmd_status command status from read failed contact counter command
- * @param transmit_power_level transmit power level for connection to this
- * device
- */
-void LogReadTxPowerLevelResult(const RawAddress& address, uint16_t handle, uint32_t cmd_status,
- int32_t transmit_power_level);
-
-/**
- * Logs when there is an event related to Bluetooth Security Manager Protocol
- *
- * @param address address of associated device
- * @param smp_cmd SMP command code associated with this event
- * @param direction direction of this SMP command
- * @param smp_fail_reason SMP pairing failure reason code from SMP spec
- */
-void LogSmpPairingEvent(const RawAddress& address, uint8_t smp_cmd,
- android::bluetooth::DirectionEnum direction, uint8_t smp_fail_reason);
-
-/**
- * Logs there is an event related Bluetooth classic pairing
- *
- * @param address address of associated device
- * @param handle connection handle of this event,
- * {@link kUnknownConnectionHandle} if unknown
- * @param hci_cmd HCI command associated with this event
- * @param hci_event HCI event associated with this event
- * @param cmd_status Command status associated with this event
- * @param reason_code Reason code associated with this event
- * @param event_value A status value related to this specific event
- */
-void LogClassicPairingEvent(const RawAddress& address, uint16_t handle, uint32_t hci_cmd,
- uint16_t hci_event, uint16_t cmd_status, uint16_t reason_code,
- int64_t event_value);
-
-/**
- * Logs when certain Bluetooth SDP attributes are discovered
- *
- * @param address address of associated device
- * @param protocol_uuid 16 bit protocol UUID from Bluetooth Assigned Numbers
- * @param attribute_id 16 bit attribute ID from Bluetooth Assigned Numbers
- * @param attribute_size size of this attribute
- * @param attribute_value pointer to the attribute data, must be larger than
- * attribute_size
- */
-void LogSdpAttribute(const RawAddress& address, uint16_t protocol_uuid, uint16_t attribute_id,
- size_t attribute_size, const char* attribute_value);
-
-/**
- * Logs when there is a change in Bluetooth socket connection state
- *
- * @param address address of associated device, empty if this is a server port
- * @param port port of this socket connection
- * @param type type of socket
- * @param connection_state socket connection state
- * @param tx_bytes number of bytes transmitted
- * @param rx_bytes number of bytes received
- * @param server_port server port of this socket, if any. When both
- * |server_port| and |port| fields are populated, |port| must be spawned
- * by |server_port|
- * @param socket_role role of this socket, server or connection
- * @param uid socket owner's uid
- */
-void LogSocketConnectionState(const RawAddress& address, int port, int type,
- android::bluetooth::SocketConnectionstateEnum connection_state,
- int64_t tx_bytes, int64_t rx_bytes, int uid, int server_port,
- android::bluetooth::SocketRoleEnum socket_role);
-
-/**
- * Logs when a Bluetooth device's manufacturer information is learnt
- *
- * @param address address of associated device
- * @param source_type where is this device info obtained from
- * @param source_name name of the data source, internal or external
- * @param manufacturer name of the manufacturer of this device
- * @param model model of this device
- * @param hardware_version hardware version of this device
- * @param software_version software version of this device
- */
-void LogManufacturerInfo(const RawAddress& address,
- android::bluetooth::AddressTypeEnum address_type,
- android::bluetooth::DeviceInfoSrcEnum source_type,
- const std::string& source_name, const std::string& manufacturer,
- const std::string& model, const std::string& hardware_version,
- const std::string& software_version);
-
-/**
- * Logs when received Bluetooth HAL crash reason report.
- *
- * @param address current connected address.
- * @param error_code the crash reason from bluetooth hal
- * @param vendor_error_code the vendor crash reason from bluetooth Firmware
- */
-void LogBluetoothHalCrashReason(const RawAddress& address, uint32_t error_code,
- uint32_t vendor_error_code);
-
void LogLeAudioConnectionSessionReported(
int32_t group_size, int32_t group_metric_id, int64_t connection_duration_nanos,
const std::vector<int64_t>& device_connecting_offset_nanos,
@@ -262,5 +63,4 @@ void LogLeAudioConnectionSessionReported(
void LogLeAudioBroadcastSessionReported(int64_t duration_nanos);
} // namespace common
-
} // namespace bluetooth
diff --git a/system/common/metrics_linux.cc b/system/common/metrics_linux.cc
index e49dd1d2cf..e886c05bf3 100644
--- a/system/common/metrics_linux.cc
+++ b/system/common/metrics_linux.cc
@@ -16,78 +16,18 @@
*
******************************************************************************/
-#include <bluetooth/log.h>
+#include <cstdint>
+#include <vector>
#include "common/metrics.h"
#include "types/raw_address.h"
namespace bluetooth {
-
namespace common {
-void LogClassicPairingEvent(const RawAddress& /* address */, uint16_t /* handle */,
- uint32_t /* hci_cmd */, uint16_t /* hci_event */,
- uint16_t /* cmd_status */, uint16_t /* reason_code */,
- int64_t /* event_value */) {}
-
-void LogSocketConnectionState(const RawAddress& /* address */, int /* port */, int /* type */,
- android::bluetooth::SocketConnectionstateEnum /* connection_state */,
- int64_t /* tx_bytes */, int64_t /* rx_bytes */, int /* uid */,
- int /* server_port */,
- android::bluetooth::SocketRoleEnum /* socket_role */) {}
-
-void LogHciTimeoutEvent(uint32_t /* hci_cmd */) {}
-
-void LogA2dpAudioUnderrunEvent(const RawAddress& /* address */,
- uint64_t /* encoding_interval_millis */,
- int /* num_missing_pcm_bytes */) {}
-
-void LogA2dpAudioOverrunEvent(const RawAddress& /* address */,
- uint64_t /* encoding_interval_millis */,
- int /* num_dropped_buffers */, int /* num_dropped_encoded_frames */,
- int /* num_dropped_encoded_bytes */) {}
-
-void LogA2dpPlaybackEvent(const RawAddress& /* address */, int /* playback_state */,
- int /* audio_coding_mode */) {}
-
-void LogBluetoothHalCrashReason(const RawAddress& /* address */, uint32_t /* error_code */,
- uint32_t /* vendor_error_code */) {}
-
-void LogReadRssiResult(const RawAddress& /* address */, uint16_t /* handle */,
- uint32_t /* cmd_status */, int8_t /* rssi */) {}
-
-void LogReadFailedContactCounterResult(const RawAddress& /* address */, uint16_t /* handle */,
- uint32_t /* cmd_status */,
- int32_t /* failed_contact_counter */) {}
-
-void LogReadTxPowerLevelResult(const RawAddress& /* address */, uint16_t /* handle */,
- uint32_t /* cmd_status */, int32_t /* transmit_power_level */) {}
-
void LogRemoteVersionInfo(uint16_t /* handle */, uint8_t /* status */, uint8_t /* version */,
uint16_t /* manufacturer_name */, uint16_t /* subversion */) {}
-void LogLinkLayerConnectionEvent(const RawAddress* /* address */, uint32_t /* connection_handle */,
- android::bluetooth::DirectionEnum /* direction */,
- uint16_t /* link_type */, uint32_t /* hci_cmd */,
- uint16_t /* hci_event */, uint16_t /* hci_ble_event */,
- uint16_t /* cmd_status */, uint16_t /* reason_code */) {}
-
-void LogManufacturerInfo(const RawAddress& /* address */,
- android::bluetooth::AddressTypeEnum /* address_type */,
- android::bluetooth::DeviceInfoSrcEnum /* source_type */,
- const std::string& /* source_name */,
- const std::string& /* manufacturer */, const std::string& /* model */,
- const std::string& /* hardware_version */,
- const std::string& /* software_version */) {}
-
-void LogSdpAttribute(const RawAddress& /* address */, uint16_t /* protocol_uuid */,
- uint16_t /* attribute_id */, size_t /* attribute_size */,
- const char* /* attribute_value */) {}
-
-void LogSmpPairingEvent(const RawAddress& /* address */, uint8_t /* smp_cmd */,
- android::bluetooth::DirectionEnum /* direction */,
- uint8_t /* smp_fail_reason */) {}
-
void LogLeAudioConnectionSessionReported(
int32_t /* group_size */, int32_t /* group_metric_id */,
int64_t /* connection_duration_nanos */,
@@ -104,5 +44,4 @@ void LogLeAudioConnectionSessionReported(
void LogLeAudioBroadcastSessionReported(int64_t /* duration_nanos */) {}
} // namespace common
-
} // namespace bluetooth
diff --git a/system/conf/interop_database.conf b/system/conf/interop_database.conf
index ecf3da0b07..d921db421d 100644
--- a/system/conf/interop_database.conf
+++ b/system/conf/interop_database.conf
@@ -895,3 +895,8 @@ BSK10 = Name_Based
[INTEROP_DISABLE_HF_PROFILE]
JBL Flip 5 = Name_Based
JBL Flip 6 = Name_Based
+
+# Some devices don't respond to LE appearance read request.
+[INTEROP_DISABLE_READ_LE_APPEARANCE]
+L1_L = Name_Based
+L1_R = Name_Based
diff --git a/system/device/include/interop.h b/system/device/include/interop.h
index 22233bcd65..d72315d1b0 100644
--- a/system/device/include/interop.h
+++ b/system/device/include/interop.h
@@ -358,16 +358,20 @@ typedef enum {
// Peer can request proper latency based on its power state later.
INTEROP_HID_PREF_CONN_ZERO_LATENCY,
- // Some HOGP devices have the report map longer than the maximum GATT attribute value length (512
- // bytes).
+ // Some HOGP devices have the report map longer than the maximum GATT
+ // attribute value length (512 bytes).
INTEROP_HOGP_LONG_REPORT,
- // Some HOGP devices requires MTU exchange be part of the initial setup to function.
+ // Some HOGP devices requires MTU exchange be part of the initial setup to
+ // function.
INTEROP_HOGP_FORCE_MTU_EXCHANGE,
// Some devices claim to support HFP in EIR but does not actually support it.
INTEROP_DISABLE_HF_PROFILE,
+ // Some devices don't respond to LE appearance read request.
+ INTEROP_DISABLE_READ_LE_APPEARANCE,
+
END_OF_INTEROP_LIST
} interop_feature_t;
diff --git a/system/device/src/interop.cc b/system/device/src/interop.cc
index 60d90cf6d6..44313664ed 100644
--- a/system/device/src/interop.cc
+++ b/system/device/src/interop.cc
@@ -392,6 +392,7 @@ static const char* interop_feature_string_(const interop_feature_t feature) {
CASE_RETURN_STR(INTEROP_HOGP_LONG_REPORT);
CASE_RETURN_STR(INTEROP_HOGP_FORCE_MTU_EXCHANGE);
CASE_RETURN_STR(INTEROP_DISABLE_HF_PROFILE);
+ CASE_RETURN_STR(INTEROP_DISABLE_READ_LE_APPEARANCE);
}
return UNKNOWN_INTEROP_FEATURE;
}
diff --git a/system/gd/Android.bp b/system/gd/Android.bp
index 26f31f0b8e..9a6bd02551 100644
--- a/system/gd/Android.bp
+++ b/system/gd/Android.bp
@@ -357,8 +357,8 @@ cc_test {
srcs: [
":BluetoothPacketTestSources",
":TestCommonMockFunctions",
+ ":TestMockMainShim",
":TestMockMainShimEntry",
- ":TestMockStackMetrics",
"common/bidi_queue_unittest.cc",
"common/blocking_queue_unittest.cc",
"common/byte_array_test.cc",
@@ -414,6 +414,9 @@ cc_test {
"storage/mutation_test.cc",
"storage/storage_module_test.cc",
],
+ cflags: [
+ "-DUSE_FAKE_TIMERS",
+ ],
static_libs: [
"bluetooth_flags_c_lib_for_test",
"libbase",
@@ -581,11 +584,12 @@ cc_fuzz {
defaults: ["gd_fuzz_defaults"],
srcs: [
":TestCommonMockFunctions",
- ":TestMockStackMetrics",
+ ":TestMockMainShim",
"hci/fuzz/acl_manager_fuzz_test.cc",
],
include_dirs: [
"packages/modules/Bluetooth/system",
+ "packages/modules/Bluetooth/system/include",
],
static_libs: [
"libbt-platform-protos-lite",
diff --git a/system/gd/AndroidTestTemplate.xml b/system/gd/AndroidTestTemplate.xml
index 4083baac14..92e0a83ae1 100644
--- a/system/gd/AndroidTestTemplate.xml
+++ b/system/gd/AndroidTestTemplate.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2018 The Android Open Source Project
+<!-- Copyright (C) 2018 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.
diff --git a/system/gd/benchmark.cc b/system/gd/benchmark.cc
index 2b11c898d5..923b0c76e7 100644
--- a/system/gd/benchmark.cc
+++ b/system/gd/benchmark.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/common/audit_log.cc b/system/gd/common/audit_log.cc
index 36cee3c801..e83c2894f8 100644
--- a/system/gd/common/audit_log.cc
+++ b/system/gd/common/audit_log.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/system/gd/common/audit_log.h b/system/gd/common/audit_log.h
index b129bc7411..70a160870e 100644
--- a/system/gd/common/audit_log.h
+++ b/system/gd/common/audit_log.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/system/gd/common/bidi_queue.h b/system/gd/common/bidi_queue.h
index 98271887eb..4dad186562 100644
--- a/system/gd/common/bidi_queue.h
+++ b/system/gd/common/bidi_queue.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/common/bidi_queue_unittest.cc b/system/gd/common/bidi_queue_unittest.cc
index 3505d16cdb..2235c3cc71 100644
--- a/system/gd/common/bidi_queue_unittest.cc
+++ b/system/gd/common/bidi_queue_unittest.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/common/bind.h b/system/gd/common/bind.h
index 9385c79dc5..fc1c9cdb80 100644
--- a/system/gd/common/bind.h
+++ b/system/gd/common/bind.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/common/blocking_queue.h b/system/gd/common/blocking_queue.h
index 4b68e514ab..25b46163d7 100644
--- a/system/gd/common/blocking_queue.h
+++ b/system/gd/common/blocking_queue.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/common/blocking_queue_unittest.cc b/system/gd/common/blocking_queue_unittest.cc
index 2b109ffe5f..623dc026bd 100644
--- a/system/gd/common/blocking_queue_unittest.cc
+++ b/system/gd/common/blocking_queue_unittest.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/common/byte_array.h b/system/gd/common/byte_array.h
index b7183c4d2d..daff291385 100644
--- a/system/gd/common/byte_array.h
+++ b/system/gd/common/byte_array.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/common/byte_array_test.cc b/system/gd/common/byte_array_test.cc
index b9a64b3882..29ae26494b 100644
--- a/system/gd/common/byte_array_test.cc
+++ b/system/gd/common/byte_array_test.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/common/callback.h b/system/gd/common/callback.h
index 7bf6f3a4ef..5fa3ee991c 100644
--- a/system/gd/common/callback.h
+++ b/system/gd/common/callback.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/common/circular_buffer.h b/system/gd/common/circular_buffer.h
index 6132f2e51c..bfb4b4252a 100644
--- a/system/gd/common/circular_buffer.h
+++ b/system/gd/common/circular_buffer.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/common/circular_buffer_test.cc b/system/gd/common/circular_buffer_test.cc
index 618388858b..5b465de723 100644
--- a/system/gd/common/circular_buffer_test.cc
+++ b/system/gd/common/circular_buffer_test.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/common/contextual_callback.h b/system/gd/common/contextual_callback.h
index 548936d68b..6a6602e217 100644
--- a/system/gd/common/contextual_callback.h
+++ b/system/gd/common/contextual_callback.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/common/i_postable_context.h b/system/gd/common/i_postable_context.h
index b421579ca8..13ec14db29 100644
--- a/system/gd/common/i_postable_context.h
+++ b/system/gd/common/i_postable_context.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/common/list_map.h b/system/gd/common/list_map.h
index 1b63302806..8c1b014753 100644
--- a/system/gd/common/list_map.h
+++ b/system/gd/common/list_map.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/common/list_map_test.cc b/system/gd/common/list_map_test.cc
index 991fd25c58..d9a6c149b3 100644
--- a/system/gd/common/list_map_test.cc
+++ b/system/gd/common/list_map_test.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/common/lru_cache.h b/system/gd/common/lru_cache.h
index 303688d55f..6f5c2340f5 100644
--- a/system/gd/common/lru_cache.h
+++ b/system/gd/common/lru_cache.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/common/lru_cache_test.cc b/system/gd/common/lru_cache_test.cc
index 555a04edd2..166eb94561 100644
--- a/system/gd/common/lru_cache_test.cc
+++ b/system/gd/common/lru_cache_test.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/common/multi_priority_queue.h b/system/gd/common/multi_priority_queue.h
index d48f0bffb0..9dcc751c8e 100644
--- a/system/gd/common/multi_priority_queue.h
+++ b/system/gd/common/multi_priority_queue.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright 2021 The Android Open Source Project
+ * Copyright (C) 2021 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.
diff --git a/system/gd/common/multi_priority_queue_test.cc b/system/gd/common/multi_priority_queue_test.cc
index 435e1ad3cd..5691a7ca7a 100644
--- a/system/gd/common/multi_priority_queue_test.cc
+++ b/system/gd/common/multi_priority_queue_test.cc
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright 2021 The Android Open Source Project
+ * Copyright (C) 2021 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.
diff --git a/system/gd/common/numbers.h b/system/gd/common/numbers.h
index e31bebbee3..5256093fa5 100644
--- a/system/gd/common/numbers.h
+++ b/system/gd/common/numbers.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/common/numbers_test.cc b/system/gd/common/numbers_test.cc
index bf4159f934..c5afad5cdc 100644
--- a/system/gd/common/numbers_test.cc
+++ b/system/gd/common/numbers_test.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/common/postable_context.h b/system/gd/common/postable_context.h
index 4a9514870f..332952df31 100644
--- a/system/gd/common/postable_context.h
+++ b/system/gd/common/postable_context.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 The Android Open Source Project
+ * Copyright (C) 2024 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.
diff --git a/system/gd/common/stop_watch.cc b/system/gd/common/stop_watch.cc
index b9f95bbcbe..5425ab7ed7 100644
--- a/system/gd/common/stop_watch.cc
+++ b/system/gd/common/stop_watch.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/common/stop_watch.h b/system/gd/common/stop_watch.h
index 792229172e..1a33d10770 100644
--- a/system/gd/common/stop_watch.h
+++ b/system/gd/common/stop_watch.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/common/strings.cc b/system/gd/common/strings.cc
index db42acfcf4..ba450acf65 100644
--- a/system/gd/common/strings.cc
+++ b/system/gd/common/strings.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/common/strings.h b/system/gd/common/strings.h
index 5593715eb2..ab8756e08e 100644
--- a/system/gd/common/strings.h
+++ b/system/gd/common/strings.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/common/strings_test.cc b/system/gd/common/strings_test.cc
index 9188eae528..24b4adedc6 100644
--- a/system/gd/common/strings_test.cc
+++ b/system/gd/common/strings_test.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/common/sync_map_count.h b/system/gd/common/sync_map_count.h
index b9cfab3049..10e63cdd08 100644
--- a/system/gd/common/sync_map_count.h
+++ b/system/gd/common/sync_map_count.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2021 The Android Open Source Project
+ * Copyright (C) 2021 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.
diff --git a/system/gd/common/sync_map_count_test.cc b/system/gd/common/sync_map_count_test.cc
index 0e29c32467..04911b87bc 100644
--- a/system/gd/common/sync_map_count_test.cc
+++ b/system/gd/common/sync_map_count_test.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2021 The Android Open Source Project
+ * Copyright (C) 2021 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.
diff --git a/system/gd/common/testing/bind_test_util.h b/system/gd/common/testing/bind_test_util.h
index 7db92045f7..d3f8996265 100644
--- a/system/gd/common/testing/bind_test_util.h
+++ b/system/gd/common/testing/bind_test_util.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/common/testing/wired_pair_of_bidi_queues.h b/system/gd/common/testing/wired_pair_of_bidi_queues.h
index ca401cb9e0..663727f1df 100644
--- a/system/gd/common/testing/wired_pair_of_bidi_queues.h
+++ b/system/gd/common/testing/wired_pair_of_bidi_queues.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/common/type_helper.h b/system/gd/common/type_helper.h
index 2f4a9d74fe..7ffd9b7363 100644
--- a/system/gd/common/type_helper.h
+++ b/system/gd/common/type_helper.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/crypto_toolbox/crypto_toolbox_test.cc b/system/gd/crypto_toolbox/crypto_toolbox_test.cc
index 35ab082d89..382d7035d4 100644
--- a/system/gd/crypto_toolbox/crypto_toolbox_test.cc
+++ b/system/gd/crypto_toolbox/crypto_toolbox_test.cc
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright 2018 The Android Open Source Project
+ * Copyright (C) 2018 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.
diff --git a/system/gd/fuzz/helpers.cc b/system/gd/fuzz/helpers.cc
index a03f04aab8..1efe175dda 100644
--- a/system/gd/fuzz/helpers.cc
+++ b/system/gd/fuzz/helpers.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/fuzz/helpers.h b/system/gd/fuzz/helpers.h
index 7b90ff82bc..ed7f3ee852 100644
--- a/system/gd/fuzz/helpers.h
+++ b/system/gd/fuzz/helpers.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/fuzz_test.cc b/system/gd/fuzz_test.cc
index bdb007b295..73ad2fd65e 100644
--- a/system/gd/fuzz_test.cc
+++ b/system/gd/fuzz_test.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/hal/fuzz/fuzz_hci_hal.cc b/system/gd/hal/fuzz/fuzz_hci_hal.cc
index a0db9f01d9..3d9afec3a8 100644
--- a/system/gd/hal/fuzz/fuzz_hci_hal.cc
+++ b/system/gd/hal/fuzz/fuzz_hci_hal.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/hal/fuzz/fuzz_hci_hal.h b/system/gd/hal/fuzz/fuzz_hci_hal.h
index 07a3593e7c..ab9fc7ee64 100644
--- a/system/gd/hal/fuzz/fuzz_hci_hal.h
+++ b/system/gd/hal/fuzz/fuzz_hci_hal.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/hal/hci_backend.h b/system/gd/hal/hci_backend.h
index 5c107ef8a1..657d771bbc 100644
--- a/system/gd/hal/hci_backend.h
+++ b/system/gd/hal/hci_backend.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 The Android Open Source Project
+ * Copyright (C) 2024 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.
diff --git a/system/gd/hal/hci_backend_aidl.cc b/system/gd/hal/hci_backend_aidl.cc
index 04bd67f992..93994c374d 100644
--- a/system/gd/hal/hci_backend_aidl.cc
+++ b/system/gd/hal/hci_backend_aidl.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 The Android Open Source Project
+ * Copyright (C) 2024 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.
diff --git a/system/gd/hal/hci_backend_hidl.cc b/system/gd/hal/hci_backend_hidl.cc
index 0fb2729307..79f69a44f0 100644
--- a/system/gd/hal/hci_backend_hidl.cc
+++ b/system/gd/hal/hci_backend_hidl.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 The Android Open Source Project
+ * Copyright (C) 2024 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.
diff --git a/system/gd/hal/hci_hal.h b/system/gd/hal/hci_hal.h
index d016d354f2..2c028c3b6f 100644
--- a/system/gd/hal/hci_hal.h
+++ b/system/gd/hal/hci_hal.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
@@ -51,6 +51,10 @@ public:
// Send an ISO data packet from the controller to the host
// @param data the ISO HCI packet to be passed to the host stack
virtual void isoDataReceived(HciPacket data) = 0;
+
+ // This function is invoked when the controller encounters an error requiring
+ // the Bluetooth stack to initiate a reset.
+ virtual void controllerNeedsReset() {}
};
// Mirrors hardware/interfaces/bluetooth/1.0/IBluetoothHci.hal in Android
@@ -101,9 +105,6 @@ public:
// Get the MSFT opcode (as specified in Microsoft-defined Bluetooth HCI
// extensions)
virtual uint16_t getMsftOpcode() { return 0; }
-
- // Mark the controller as broken to prevent further read / write operation.
- virtual void markControllerBroken() { return; }
};
// LINT.ThenChange(fuzz/fuzz_hci_hal.h)
diff --git a/system/gd/hal/hci_hal_android.cc b/system/gd/hal/hci_hal_android.cc
index 8f1246d064..f548080d83 100644
--- a/system/gd/hal/hci_hal_android.cc
+++ b/system/gd/hal/hci_hal_android.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 The Android Open Source Project
+ * Copyright (C) 2024 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.
diff --git a/system/gd/hal/hci_hal_android_test.cc b/system/gd/hal/hci_hal_android_test.cc
index 471e54bb70..f128f508cf 100644
--- a/system/gd/hal/hci_hal_android_test.cc
+++ b/system/gd/hal/hci_hal_android_test.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 The Android Open Source Project
+ * Copyright (C) 2024 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.
@@ -20,6 +20,7 @@
#include <queue>
#include <thread>
+#include "com_android_bluetooth_flags.h"
#include "hal/hci_backend.h"
#include "hal/hci_hal.h"
#include "os/thread.h"
@@ -79,10 +80,13 @@ protected:
}
void TearDown() override {
- fake_registry_.StopAll();
handler_->Clear();
- delete thread_;
+ if (com::android::bluetooth::flags::same_handler_for_all_modules()) {
+ handler_->WaitUntilStopped(bluetooth::kHandlerStopTimeout);
+ }
+ fake_registry_.StopAll();
delete handler_;
+ delete thread_;
}
HciHal* hal;
diff --git a/system/gd/hal/hci_hal_fake.cc b/system/gd/hal/hci_hal_fake.cc
index 7d396dd571..781dde6749 100644
--- a/system/gd/hal/hci_hal_fake.cc
+++ b/system/gd/hal/hci_hal_fake.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 The Android Open Source Project
+ * Copyright (C) 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.
diff --git a/system/gd/hal/hci_hal_fake.h b/system/gd/hal/hci_hal_fake.h
index 1d94f768ce..9d58064297 100644
--- a/system/gd/hal/hci_hal_fake.h
+++ b/system/gd/hal/hci_hal_fake.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 The Android Open Source Project
+ * Copyright (C) 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.
diff --git a/system/gd/hal/hci_hal_host.cc b/system/gd/hal/hci_hal_host.cc
index 970a2ae48c..bf020a2e02 100644
--- a/system/gd/hal/hci_hal_host.cc
+++ b/system/gd/hal/hci_hal_host.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
@@ -262,9 +262,6 @@ public:
void sendHciCommand(HciPacket command) override {
std::lock_guard<std::mutex> lock(api_mutex_);
- if (controller_broken_) {
- return;
- }
log::assert_that(sock_fd_ != INVALID_FD, "assert failed: sock_fd_ != INVALID_FD");
std::vector<uint8_t> packet = std::move(command);
btsnoop_logger_->Capture(packet, SnoopLogger::Direction::OUTGOING,
@@ -275,9 +272,6 @@ public:
void sendAclData(HciPacket data) override {
std::lock_guard<std::mutex> lock(api_mutex_);
- if (controller_broken_) {
- return;
- }
log::assert_that(sock_fd_ != INVALID_FD, "assert failed: sock_fd_ != INVALID_FD");
std::vector<uint8_t> packet = std::move(data);
btsnoop_logger_->Capture(packet, SnoopLogger::Direction::OUTGOING,
@@ -288,10 +282,6 @@ public:
void sendScoData(HciPacket data) override {
std::lock_guard<std::mutex> lock(api_mutex_);
- if (controller_broken_) {
- return;
- }
-
log::assert_that(sock_fd_ != INVALID_FD, "assert failed: sock_fd_ != INVALID_FD");
std::vector<uint8_t> packet = std::move(data);
btsnoop_logger_->Capture(packet, SnoopLogger::Direction::OUTGOING,
@@ -302,9 +292,6 @@ public:
void sendIsoData(HciPacket data) override {
std::lock_guard<std::mutex> lock(api_mutex_);
- if (controller_broken_) {
- return;
- }
log::assert_that(sock_fd_ != INVALID_FD, "assert failed: sock_fd_ != INVALID_FD");
std::vector<uint8_t> packet = std::move(data);
btsnoop_logger_->Capture(packet, SnoopLogger::Direction::OUTGOING,
@@ -317,15 +304,6 @@ public:
return os::Management::getInstance().getVendorSpecificCode(MGMT_VS_OPCODE_MSFT);
}
- void markControllerBroken() override {
- std::lock_guard<std::mutex> lock(api_mutex_);
- if (controller_broken_) {
- log::error("Controller already marked as broken!");
- return;
- }
- controller_broken_ = true;
- }
-
protected:
void ListDependencies(ModuleList* list) const { list->add<LinkClocker>(); }
@@ -337,8 +315,7 @@ protected:
// We don't want to crash when the chipset is broken.
if (sock_fd_ == INVALID_FD) {
log::error("Failed to connect to HCI socket. Aborting HAL initialization process.");
- controller_broken_ = true;
- kill(getpid(), SIGTERM);
+ incoming_packet_callback_->controllerNeedsReset();
return;
}
@@ -392,7 +369,6 @@ private:
std::queue<std::vector<uint8_t>> hci_outgoing_queue_;
SnoopLogger* btsnoop_logger_ = nullptr;
LinkClocker* link_clocker_ = nullptr;
- bool controller_broken_ = false;
void write_to_fd(HciPacket packet) {
// TODO(chromeos-bt-team@): replace this with new queue when it's ready
@@ -414,8 +390,8 @@ private:
hci_outgoing_queue_.pop();
if (bytes_written == -1) {
log::error("Can't write to socket: {}", strerror(errno));
- markControllerBroken();
- kill(getpid(), SIGTERM);
+ incoming_packet_callback_->controllerNeedsReset();
+ return;
}
if (hci_outgoing_queue_.empty()) {
hci_incoming_thread_.GetReactor()->ModifyRegistration(reactable_,
@@ -439,15 +415,13 @@ private:
// we don't want crash when the chipset is broken.
if (received_size == -1) {
log::error("Can't receive from socket: {}", strerror(errno));
- markControllerBroken();
- kill(getpid(), SIGTERM);
+ incoming_packet_callback_->controllerNeedsReset();
return;
}
if (received_size == 0) {
log::warn("Can't read H4 header. EOF received");
- markControllerBroken();
- kill(getpid(), SIGTERM);
+ incoming_packet_callback_->controllerNeedsReset();
return;
}
diff --git a/system/gd/hal/hci_hal_host.h b/system/gd/hal/hci_hal_host.h
index 9f1350b265..42712d791a 100644
--- a/system/gd/hal/hci_hal_host.h
+++ b/system/gd/hal/hci_hal_host.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/hal/hci_hal_host_rootcanal.cc b/system/gd/hal/hci_hal_host_rootcanal.cc
index 612372a962..065711059a 100644
--- a/system/gd/hal/hci_hal_host_rootcanal.cc
+++ b/system/gd/hal/hci_hal_host_rootcanal.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/hal/hci_hal_host_test.cc b/system/gd/hal/hci_hal_host_test.cc
index 9f50867f59..d4539d6c3b 100644
--- a/system/gd/hal/hci_hal_host_test.cc
+++ b/system/gd/hal/hci_hal_host_test.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
@@ -32,6 +32,7 @@
#include <utility>
#include <vector>
+#include "com_android_bluetooth_flags.h"
#include "hal/hci_hal.h"
#include "hal/serialize_packet.h"
#include "os/thread.h"
@@ -155,12 +156,15 @@ protected:
void TearDown() override {
hal_->unregisterIncomingPacketCallback();
+ handler_->Clear();
+ if (com::android::bluetooth::flags::same_handler_for_all_modules()) {
+ handler_->WaitUntilStopped(bluetooth::kHandlerStopTimeout);
+ }
fake_registry_.StopAll();
+ delete handler_;
close(fake_server_socket_);
- handler_->Clear();
delete fake_server_;
delete thread_;
- delete handler_;
}
void SetFakeServerSocketToBlocking() {
diff --git a/system/gd/hal/link_clocker.cc b/system/gd/hal/link_clocker.cc
index f491e9ee1b..0a7ee8366a 100644
--- a/system/gd/hal/link_clocker.cc
+++ b/system/gd/hal/link_clocker.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 The Android Open Source Project
+ * Copyright (C) 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.
diff --git a/system/gd/hal/link_clocker.h b/system/gd/hal/link_clocker.h
index acabf0787b..34286bfd96 100644
--- a/system/gd/hal/link_clocker.h
+++ b/system/gd/hal/link_clocker.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 The Android Open Source Project
+ * Copyright (C) 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.
diff --git a/system/gd/hal/ranging_hal.h b/system/gd/hal/ranging_hal.h
index b22378970e..6966aedb0a 100644
--- a/system/gd/hal/ranging_hal.h
+++ b/system/gd/hal/ranging_hal.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 The Android Open Source Project
+ * Copyright (C) 2024 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.
diff --git a/system/gd/hal/ranging_hal_android.cc b/system/gd/hal/ranging_hal_android.cc
index 033ed789f0..086e651da2 100644
--- a/system/gd/hal/ranging_hal_android.cc
+++ b/system/gd/hal/ranging_hal_android.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 The Android Open Source Project
+ * Copyright (C) 2024 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.
diff --git a/system/gd/hal/ranging_hal_host.cc b/system/gd/hal/ranging_hal_host.cc
index 59282dc422..78ce007068 100644
--- a/system/gd/hal/ranging_hal_host.cc
+++ b/system/gd/hal/ranging_hal_host.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 The Android Open Source Project
+ * Copyright (C) 2024 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.
diff --git a/system/gd/hal/ranging_hal_mock.h b/system/gd/hal/ranging_hal_mock.h
index 328411353f..84696d3f64 100644
--- a/system/gd/hal/ranging_hal_mock.h
+++ b/system/gd/hal/ranging_hal_mock.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2025 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/system/gd/hal/serialize_packet.h b/system/gd/hal/serialize_packet.h
index 70466fc164..9c13f4b671 100644
--- a/system/gd/hal/serialize_packet.h
+++ b/system/gd/hal/serialize_packet.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/hal/snoop_logger.cc b/system/gd/hal/snoop_logger.cc
index a34e70162b..538d13ec3e 100644
--- a/system/gd/hal/snoop_logger.cc
+++ b/system/gd/hal/snoop_logger.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/hal/snoop_logger.h b/system/gd/hal/snoop_logger.h
index f448eef4db..b009add89c 100644
--- a/system/gd/hal/snoop_logger.h
+++ b/system/gd/hal/snoop_logger.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/hal/snoop_logger_socket_test.cc b/system/gd/hal/snoop_logger_socket_test.cc
index 85642e37ed..b40f6f5bf3 100644
--- a/system/gd/hal/snoop_logger_socket_test.cc
+++ b/system/gd/hal/snoop_logger_socket_test.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/hal/snoop_logger_socket_thread_test.cc b/system/gd/hal/snoop_logger_socket_thread_test.cc
index a967a8d2a2..726f7ab245 100644
--- a/system/gd/hal/snoop_logger_socket_thread_test.cc
+++ b/system/gd/hal/snoop_logger_socket_thread_test.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/hal/snoop_logger_test.cc b/system/gd/hal/snoop_logger_test.cc
index de42db5c06..78d9bb54e4 100644
--- a/system/gd/hal/snoop_logger_test.cc
+++ b/system/gd/hal/snoop_logger_test.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/hal/snoop_logger_tracing.cc b/system/gd/hal/snoop_logger_tracing.cc
index 415aceab19..38ce3dec33 100644
--- a/system/gd/hal/snoop_logger_tracing.cc
+++ b/system/gd/hal/snoop_logger_tracing.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2025 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/system/gd/hal/snoop_logger_tracing.h b/system/gd/hal/snoop_logger_tracing.h
index 9b4bd7be9d..ccf2a60605 100644
--- a/system/gd/hal/snoop_logger_tracing.h
+++ b/system/gd/hal/snoop_logger_tracing.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2025 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/system/gd/hal/socket_hal.h b/system/gd/hal/socket_hal.h
index 3922e29da0..3a6fba43b9 100644
--- a/system/gd/hal/socket_hal.h
+++ b/system/gd/hal/socket_hal.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 The Android Open Source Project
+ * Copyright (C) 2024 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.
diff --git a/system/gd/hal/socket_hal_android.cc b/system/gd/hal/socket_hal_android.cc
index bdbf0a8663..4e206e3d35 100644
--- a/system/gd/hal/socket_hal_android.cc
+++ b/system/gd/hal/socket_hal_android.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 The Android Open Source Project
+ * Copyright (C) 2024 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.
diff --git a/system/gd/hal/socket_hal_host.cc b/system/gd/hal/socket_hal_host.cc
index 292428a821..7ee57731cc 100644
--- a/system/gd/hal/socket_hal_host.cc
+++ b/system/gd/hal/socket_hal_host.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 The Android Open Source Project
+ * Copyright (C) 2024 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.
diff --git a/system/gd/hci/acl_builder_test.cc b/system/gd/hci/acl_builder_test.cc
index b23581e36f..6c78f0b1e9 100644
--- a/system/gd/hci/acl_builder_test.cc
+++ b/system/gd/hci/acl_builder_test.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 The Android Open Source Project
+ * Copyright (C) 2018 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.
diff --git a/system/gd/hci/acl_connection_interface.h b/system/gd/hci/acl_connection_interface.h
index f90b9909d1..ba700aca0b 100644
--- a/system/gd/hci/acl_connection_interface.h
+++ b/system/gd/hci/acl_connection_interface.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/hci/acl_manager.cc b/system/gd/hci/acl_manager.cc
index 6da8b37a6d..26b0ce70eb 100644
--- a/system/gd/hci/acl_manager.cc
+++ b/system/gd/hci/acl_manager.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
@@ -260,11 +260,6 @@ void AclManager::CreateLeConnection(AddressWithType address_with_type, bool is_d
CallOn(pimpl_->le_impl_, &le_impl::create_le_connection, address_with_type, true, is_direct);
}
-void AclManager::IsOnBackgroundList(AddressWithType address_with_type, std::promise<bool> promise) {
- CallOn(pimpl_->le_impl_, &le_impl::is_on_background_connection_list, address_with_type,
- std::move(promise));
-}
-
void AclManager::SetLeSuggestedDefaultDataParameters(uint16_t octets, uint16_t time) {
CallOn(pimpl_->le_impl_, &le_impl::set_le_suggested_default_data_parameters, octets, time);
}
diff --git a/system/gd/hci/acl_manager.h b/system/gd/hci/acl_manager.h
index 8326d479ab..2b3d523b1f 100644
--- a/system/gd/hci/acl_manager.h
+++ b/system/gd/hci/acl_manager.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
@@ -108,7 +108,6 @@ public:
// connected
virtual void CancelConnect(Address address);
virtual void RemoveFromBackgroundList(AddressWithType address_with_type);
- virtual void IsOnBackgroundList(AddressWithType address_with_type, std::promise<bool> promise);
virtual void CancelLeConnect(AddressWithType address_with_type);
diff --git a/system/gd/hci/acl_manager/acl_connection.cc b/system/gd/hci/acl_manager/acl_connection.cc
index e616416f63..28605cc033 100644
--- a/system/gd/hci/acl_manager/acl_connection.cc
+++ b/system/gd/hci/acl_manager/acl_connection.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/hci/acl_manager/acl_connection.h b/system/gd/hci/acl_manager/acl_connection.h
index 0a7e7d1f07..03fe48755d 100644
--- a/system/gd/hci/acl_manager/acl_connection.h
+++ b/system/gd/hci/acl_manager/acl_connection.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/hci/acl_manager/acl_fragmenter.cc b/system/gd/hci/acl_manager/acl_fragmenter.cc
index 3264ded78d..af0ced547e 100644
--- a/system/gd/hci/acl_manager/acl_fragmenter.cc
+++ b/system/gd/hci/acl_manager/acl_fragmenter.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/hci/acl_manager/acl_fragmenter.h b/system/gd/hci/acl_manager/acl_fragmenter.h
index 28d14c1a3a..26fd7ea482 100644
--- a/system/gd/hci/acl_manager/acl_fragmenter.h
+++ b/system/gd/hci/acl_manager/acl_fragmenter.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/hci/acl_manager/acl_scheduler.cc b/system/gd/hci/acl_manager/acl_scheduler.cc
index f7c47505af..65981d9c23 100644
--- a/system/gd/hci/acl_manager/acl_scheduler.cc
+++ b/system/gd/hci/acl_manager/acl_scheduler.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/system/gd/hci/acl_manager/acl_scheduler.h b/system/gd/hci/acl_manager/acl_scheduler.h
index c90ab11983..4c61461be1 100644
--- a/system/gd/hci/acl_manager/acl_scheduler.h
+++ b/system/gd/hci/acl_manager/acl_scheduler.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/system/gd/hci/acl_manager/acl_scheduler_test.cc b/system/gd/hci/acl_manager/acl_scheduler_test.cc
index fa5b0fc164..21414c5925 100644
--- a/system/gd/hci/acl_manager/acl_scheduler_test.cc
+++ b/system/gd/hci/acl_manager/acl_scheduler_test.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/system/gd/hci/acl_manager/assembler.h b/system/gd/hci/acl_manager/assembler.h
index d126a980a2..00e63e1e38 100644
--- a/system/gd/hci/acl_manager/assembler.h
+++ b/system/gd/hci/acl_manager/assembler.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/hci/acl_manager/classic_acl_connection.cc b/system/gd/hci/acl_manager/classic_acl_connection.cc
index 301211c345..4a13a1335a 100644
--- a/system/gd/hci/acl_manager/classic_acl_connection.cc
+++ b/system/gd/hci/acl_manager/classic_acl_connection.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/hci/acl_manager/classic_acl_connection.h b/system/gd/hci/acl_manager/classic_acl_connection.h
index 75dacf52d1..62c11b3196 100644
--- a/system/gd/hci/acl_manager/classic_acl_connection.h
+++ b/system/gd/hci/acl_manager/classic_acl_connection.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/hci/acl_manager/classic_acl_connection_test.cc b/system/gd/hci/acl_manager/classic_acl_connection_test.cc
index 32949927e7..e6167285c8 100644
--- a/system/gd/hci/acl_manager/classic_acl_connection_test.cc
+++ b/system/gd/hci/acl_manager/classic_acl_connection_test.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/system/gd/hci/acl_manager/classic_impl.h b/system/gd/hci/acl_manager/classic_impl.h
index ecef1f9414..586b64549c 100644
--- a/system/gd/hci/acl_manager/classic_impl.h
+++ b/system/gd/hci/acl_manager/classic_impl.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/hci/acl_manager/classic_impl_test.cc b/system/gd/hci/acl_manager/classic_impl_test.cc
index 6b57eac662..11e89bb633 100644
--- a/system/gd/hci/acl_manager/classic_impl_test.cc
+++ b/system/gd/hci/acl_manager/classic_impl_test.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 The Android Open Source Project
+ * Copyright (C) 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.
diff --git a/system/gd/hci/acl_manager/connection_callbacks.h b/system/gd/hci/acl_manager/connection_callbacks.h
index 8804b5ad9d..2998f20724 100644
--- a/system/gd/hci/acl_manager/connection_callbacks.h
+++ b/system/gd/hci/acl_manager/connection_callbacks.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/hci/acl_manager/connection_callbacks_mock.h b/system/gd/hci/acl_manager/connection_callbacks_mock.h
index 64bd067db2..5018331c42 100644
--- a/system/gd/hci/acl_manager/connection_callbacks_mock.h
+++ b/system/gd/hci/acl_manager/connection_callbacks_mock.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 The Android Open Source Project
+ * Copyright (C) 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.
diff --git a/system/gd/hci/acl_manager/connection_management_callbacks.h b/system/gd/hci/acl_manager/connection_management_callbacks.h
index 55d0062c0a..b4546a3a2d 100644
--- a/system/gd/hci/acl_manager/connection_management_callbacks.h
+++ b/system/gd/hci/acl_manager/connection_management_callbacks.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/hci/acl_manager/connection_management_callbacks_mock.h b/system/gd/hci/acl_manager/connection_management_callbacks_mock.h
index e453ac99fc..eab69fcd39 100644
--- a/system/gd/hci/acl_manager/connection_management_callbacks_mock.h
+++ b/system/gd/hci/acl_manager/connection_management_callbacks_mock.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 The Android Open Source Project
+ * Copyright (C) 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.
diff --git a/system/gd/hci/acl_manager/le_acceptlist_callbacks.h b/system/gd/hci/acl_manager/le_acceptlist_callbacks.h
index a7b7dd5f5e..d547a79c3c 100644
--- a/system/gd/hci/acl_manager/le_acceptlist_callbacks.h
+++ b/system/gd/hci/acl_manager/le_acceptlist_callbacks.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/hci/acl_manager/le_acl_connection.cc b/system/gd/hci/acl_manager/le_acl_connection.cc
index 8e6f93be08..3b40ddc52c 100644
--- a/system/gd/hci/acl_manager/le_acl_connection.cc
+++ b/system/gd/hci/acl_manager/le_acl_connection.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/hci/acl_manager/le_acl_connection.h b/system/gd/hci/acl_manager/le_acl_connection.h
index 5052be51a7..35ef292708 100644
--- a/system/gd/hci/acl_manager/le_acl_connection.h
+++ b/system/gd/hci/acl_manager/le_acl_connection.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/hci/acl_manager/le_acl_connection_test.cc b/system/gd/hci/acl_manager/le_acl_connection_test.cc
index 5153fa4d3b..403f3fd9c4 100644
--- a/system/gd/hci/acl_manager/le_acl_connection_test.cc
+++ b/system/gd/hci/acl_manager/le_acl_connection_test.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/system/gd/hci/acl_manager/le_connection_callbacks.h b/system/gd/hci/acl_manager/le_connection_callbacks.h
index 2359c5ac32..c33dbbbe33 100644
--- a/system/gd/hci/acl_manager/le_connection_callbacks.h
+++ b/system/gd/hci/acl_manager/le_connection_callbacks.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/hci/acl_manager/le_connection_callbacks_mock.h b/system/gd/hci/acl_manager/le_connection_callbacks_mock.h
index fca3e93b89..4866ed8e29 100644
--- a/system/gd/hci/acl_manager/le_connection_callbacks_mock.h
+++ b/system/gd/hci/acl_manager/le_connection_callbacks_mock.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 The Android Open Source Project
+ * Copyright (C) 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.
diff --git a/system/gd/hci/acl_manager/le_connection_management_callbacks.h b/system/gd/hci/acl_manager/le_connection_management_callbacks.h
index 6ac56af029..d7b33c64b7 100644
--- a/system/gd/hci/acl_manager/le_connection_management_callbacks.h
+++ b/system/gd/hci/acl_manager/le_connection_management_callbacks.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/hci/acl_manager/le_connection_management_callbacks_mock.h b/system/gd/hci/acl_manager/le_connection_management_callbacks_mock.h
index bfbd214779..280dd7a860 100644
--- a/system/gd/hci/acl_manager/le_connection_management_callbacks_mock.h
+++ b/system/gd/hci/acl_manager/le_connection_management_callbacks_mock.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 The Android Open Source Project
+ * Copyright (C) 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.
diff --git a/system/gd/hci/acl_manager/le_impl.h b/system/gd/hci/acl_manager/le_impl.h
index ac3e7171f9..ce93f46e7e 100644
--- a/system/gd/hci/acl_manager/le_impl.h
+++ b/system/gd/hci/acl_manager/le_impl.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
@@ -39,11 +39,11 @@
#include "hci/hci_packets.h"
#include "hci/le_address_manager.h"
#include "macros.h"
+#include "main/shim/metrics_api.h"
#include "os/alarm.h"
#include "os/handler.h"
#include "os/system_properties.h"
#include "stack/include/btm_ble_api_types.h"
-#include "stack/include/stack_metrics_logging.h"
namespace bluetooth {
namespace hci {
@@ -426,7 +426,7 @@ public:
return;
}
- log_le_connection_status(address, true /* is_connect */, status);
+ bluetooth::shim::LogMetricLeConnectionStatus(address, true /* is_connect */, status);
const bool in_filter_accept_list = is_device_in_accept_list(remote_address);
@@ -586,7 +586,8 @@ public:
arm_on_resume_ = true;
add_device_to_accept_list(remote_address);
}
- log_le_connection_status(remote_address.GetAddress(), false /* is_connect */, reason);
+ bluetooth::shim::LogMetricLeConnectionStatus(remote_address.GetAddress(),
+ false /* is_connect */, reason);
}
void on_le_connection_update_complete(LeMetaEventView view) {
@@ -724,7 +725,8 @@ public:
}
void add_device_to_accept_list(AddressWithType address_with_type) {
- log_le_device_in_accept_list(address_with_type.GetAddress(), true /* is_add */);
+ bluetooth::shim::LogMetricLeDeviceInAcceptList(address_with_type.GetAddress(),
+ true /* is_add */);
if (connections.alreadyConnected(address_with_type)) {
log::info("Device already connected, return");
return;
@@ -747,7 +749,8 @@ public:
}
void remove_device_from_accept_list(AddressWithType address_with_type) {
- log_le_device_in_accept_list(address_with_type.GetAddress(), false /* is_add */);
+ bluetooth::shim::LogMetricLeDeviceInAcceptList(address_with_type.GetAddress(),
+ false /* is_add */);
if (accept_list.find(address_with_type) == accept_list.end()) {
log::warn("Device not in acceptlist and cannot be removed: {}", address_with_type);
return;
@@ -1132,8 +1135,9 @@ public:
remove_device_from_accept_list(address_with_type);
}
// Temporary mapping the error code to PAGE_TIMEOUT
- log_le_connection_completion(address_with_type.GetAddress(), ErrorCode::PAGE_TIMEOUT,
- true /* is locally initiated */);
+ bluetooth::shim::LogMetricLeConnectionCompletion(address_with_type.GetAddress(),
+ ErrorCode::PAGE_TIMEOUT,
+ true /* is locally initiated */);
le_client_handler_->Post(common::BindOnce(
&LeConnectionCallbacks::OnLeConnectFail, common::Unretained(le_client_callbacks_),
address_with_type, ErrorCode::CONNECTION_ACCEPT_TIMEOUT));
@@ -1249,12 +1253,6 @@ public:
background_connections_.erase(address_with_type);
}
- void is_on_background_connection_list(AddressWithType address_with_type,
- std::promise<bool> promise) {
- promise.set_value(background_connections_.find(address_with_type) !=
- background_connections_.end());
- }
-
void OnPause() override { // bluetooth::hci::LeAddressManagerCallback
if (!address_manager_registered) {
log::warn("Unregistered!");
diff --git a/system/gd/hci/acl_manager/le_impl_test.cc b/system/gd/hci/acl_manager/le_impl_test.cc
index d43d2faca1..66bc16bbd8 100644
--- a/system/gd/hci/acl_manager/le_impl_test.cc
+++ b/system/gd/hci/acl_manager/le_impl_test.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/system/gd/hci/acl_manager/round_robin_scheduler.cc b/system/gd/hci/acl_manager/round_robin_scheduler.cc
index 6abf838728..89897a82e5 100644
--- a/system/gd/hci/acl_manager/round_robin_scheduler.cc
+++ b/system/gd/hci/acl_manager/round_robin_scheduler.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
@@ -17,7 +17,6 @@
#include "hci/acl_manager/round_robin_scheduler.h"
#include <bluetooth/log.h>
-#include <com_android_bluetooth_flags.h>
#include <memory>
#include <utility>
@@ -65,10 +64,8 @@ void RoundRobinScheduler::Unregister(uint16_t handle) {
log::assert_that(acl_queue_handlers_.count(handle) == 1,
"assert failed: acl_queue_handlers_.count(handle) == 1");
- if (com::android::bluetooth::flags::drop_acl_fragment_on_disconnect()) {
- // Drop the pending fragments and recalculate number_of_sent_packets_
- drop_packet_fragments(handle);
- }
+ // Drop the pending fragments and recalculate number_of_sent_packets_
+ drop_packet_fragments(handle);
auto& acl_queue_handler = acl_queue_handlers_.find(handle)->second;
log::info("unregistering acl_queue handle={}, sent_packets={}", handle,
@@ -94,8 +91,7 @@ void RoundRobinScheduler::Unregister(uint16_t handle) {
starting_point_ = acl_queue_handlers_.begin();
// Restart sending packets if we got acl credits
- if (com::android::bluetooth::flags::drop_acl_fragment_on_disconnect() &&
- credits_reclaimed_from_zero) {
+ if (credits_reclaimed_from_zero) {
start_round_robin();
}
}
diff --git a/system/gd/hci/acl_manager/round_robin_scheduler.h b/system/gd/hci/acl_manager/round_robin_scheduler.h
index 61be5f1147..080ce0988f 100644
--- a/system/gd/hci/acl_manager/round_robin_scheduler.h
+++ b/system/gd/hci/acl_manager/round_robin_scheduler.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/hci/acl_manager/round_robin_scheduler_test.cc b/system/gd/hci/acl_manager/round_robin_scheduler_test.cc
index f2c9b5528b..b990332c9e 100644
--- a/system/gd/hci/acl_manager/round_robin_scheduler_test.cc
+++ b/system/gd/hci/acl_manager/round_robin_scheduler_test.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
@@ -16,7 +16,6 @@
#include "hci/acl_manager/round_robin_scheduler.h"
-#include <com_android_bluetooth_flags.h>
#include <gtest/gtest.h>
#include "common/bidi_queue.h"
@@ -422,8 +421,6 @@ TEST_F(RoundRobinSchedulerTest, receive_le_credit_when_next_fragment_is_classic)
}
TEST_F(RoundRobinSchedulerTest, unregister_reclaim_credits) {
- com::android::bluetooth::flags::provider_->drop_acl_fragment_on_disconnect(true);
-
uint16_t handle = 0x01;
auto connection_queue = std::make_shared<AclConnection::Queue>(20);
auto new_connection_queue = std::make_shared<AclConnection::Queue>(20);
diff --git a/system/gd/hci/acl_manager_mock.h b/system/gd/hci/acl_manager_mock.h
index 330b82bdac..75af214e5b 100644
--- a/system/gd/hci/acl_manager_mock.h
+++ b/system/gd/hci/acl_manager_mock.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/hci/acl_manager_test.cc b/system/gd/hci/acl_manager_test.cc
index e0a1c6674a..8b33dc723e 100644
--- a/system/gd/hci/acl_manager_test.cc
+++ b/system/gd/hci/acl_manager_test.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/hci/acl_manager_unittest.cc b/system/gd/hci/acl_manager_unittest.cc
index bfb132594c..848141da0b 100644
--- a/system/gd/hci/acl_manager_unittest.cc
+++ b/system/gd/hci/acl_manager_unittest.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/system/gd/hci/address_unittest.cc b/system/gd/hci/address_unittest.cc
index 0254545631..ee81f975f6 100644
--- a/system/gd/hci/address_unittest.cc
+++ b/system/gd/hci/address_unittest.cc
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/hci/address_with_type.h b/system/gd/hci/address_with_type.h
index 26c35e814d..b2a662bcae 100644
--- a/system/gd/hci/address_with_type.h
+++ b/system/gd/hci/address_with_type.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/hci/address_with_type_test.cc b/system/gd/hci/address_with_type_test.cc
index c3b8bb0db9..9128bf1f57 100644
--- a/system/gd/hci/address_with_type_test.cc
+++ b/system/gd/hci/address_with_type_test.cc
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/hci/class_of_device_unittest.cc b/system/gd/hci/class_of_device_unittest.cc
index 1d3f4f8f3a..4bcedfd84d 100644
--- a/system/gd/hci/class_of_device_unittest.cc
+++ b/system/gd/hci/class_of_device_unittest.cc
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/hci/command_interface.h b/system/gd/hci/command_interface.h
index a6781ef7c5..56b6b5f63f 100644
--- a/system/gd/hci/command_interface.h
+++ b/system/gd/hci/command_interface.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/hci/controller.cc b/system/gd/hci/controller.cc
index eaba7da848..919643f14d 100644
--- a/system/gd/hci/controller.cc
+++ b/system/gd/hci/controller.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
@@ -61,9 +61,7 @@ struct Controller::impl {
handler->BindOn(this, &Controller::impl::NumberOfCompletedPackets));
set_event_mask(kDefaultEventMask);
- if (com::android::bluetooth::flags::encryption_change_v2()) {
- set_event_mask_page_2(kDefaultEventMaskPage2);
- }
+ set_event_mask_page_2(kDefaultEventMaskPage2);
write_le_host_support(Enable::ENABLED, Enable::DISABLED);
hci_->EnqueueCommand(
diff --git a/system/gd/hci/controller.h b/system/gd/hci/controller.h
index 70609950da..6a35bb691f 100644
--- a/system/gd/hci/controller.h
+++ b/system/gd/hci/controller.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/hci/controller_interface.h b/system/gd/hci/controller_interface.h
index a9ebecd32a..a2a7b64c18 100644
--- a/system/gd/hci/controller_interface.h
+++ b/system/gd/hci/controller_interface.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 The Android Open Source Project
+ * Copyright (C) 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.
diff --git a/system/gd/hci/controller_interface_mock.h b/system/gd/hci/controller_interface_mock.h
index 36bc50a423..8b21585009 100644
--- a/system/gd/hci/controller_interface_mock.h
+++ b/system/gd/hci/controller_interface_mock.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2021 The Android Open Source Project
+ * Copyright (C) 2021 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.
diff --git a/system/gd/hci/controller_mock.h b/system/gd/hci/controller_mock.h
index fd3a7058d1..e39d721126 100644
--- a/system/gd/hci/controller_mock.h
+++ b/system/gd/hci/controller_mock.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2021 The Android Open Source Project
+ * Copyright (C) 2021 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.
diff --git a/system/gd/hci/controller_test.cc b/system/gd/hci/controller_test.cc
index fca2d3e9e2..e680a8598e 100644
--- a/system/gd/hci/controller_test.cc
+++ b/system/gd/hci/controller_test.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/hci/controller_unittest.cc b/system/gd/hci/controller_unittest.cc
index 6ab8d4d68b..cb90589637 100644
--- a/system/gd/hci/controller_unittest.cc
+++ b/system/gd/hci/controller_unittest.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/system/gd/hci/distance_measurement_interface.h b/system/gd/hci/distance_measurement_interface.h
index 9b6e7727c3..055d9e875c 100644
--- a/system/gd/hci/distance_measurement_interface.h
+++ b/system/gd/hci/distance_measurement_interface.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 The Android Open Source Project
+ * Copyright (C) 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.
diff --git a/system/gd/hci/distance_measurement_manager.cc b/system/gd/hci/distance_measurement_manager.cc
index 4fe3449b6b..6e57f2c9d5 100644
--- a/system/gd/hci/distance_measurement_manager.cc
+++ b/system/gd/hci/distance_measurement_manager.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -337,7 +337,11 @@ struct DistanceMeasurementManager::impl : bluetooth::hal::RangingHalCallback {
}
}
- void stop() { hci_layer_->UnregisterLeEventHandler(hci::SubeventCode::TRANSMIT_POWER_REPORTING); }
+ void stop() {
+ hci_layer_->UnregisterLeEventHandler(hci::SubeventCode::TRANSMIT_POWER_REPORTING);
+ cs_requester_trackers_.clear();
+ cs_responder_trackers_.clear();
+ }
void register_distance_measurement_callbacks(DistanceMeasurementCallbacks* callbacks) {
distance_measurement_callbacks_ = callbacks;
@@ -437,6 +441,8 @@ struct DistanceMeasurementManager::impl : bluetooth::hal::RangingHalCallback {
it->second.measurement_ongoing = true;
it->second.waiting_for_start_callback = true;
it->second.local_hci_role = local_hci_role;
+ it->second.retry_counter_for_create_config = 0;
+ it->second.retry_counter_for_cs_enable = 0;
return true;
}
@@ -841,6 +847,7 @@ struct DistanceMeasurementManager::impl : bluetooth::hal::RangingHalCallback {
static void reset_tracker_on_stopped(CsTracker& cs_tracker) {
cs_tracker.measurement_ongoing = false;
cs_tracker.state = CsTrackerState::STOPPED;
+ cs_tracker.procedure_data_list.clear();
}
void handle_cs_setup_failure(uint16_t connection_handle, DistanceMeasurementErrorCode errorCode) {
@@ -902,7 +909,7 @@ struct DistanceMeasurementManager::impl : bluetooth::hal::RangingHalCallback {
if (cs_requester_trackers_.find(connection_handle) != cs_requester_trackers_.end()) {
reset_tracker_on_stopped(cs_requester_trackers_[connection_handle]);
}
- } else if (status_view.GetStatus() != ErrorCode::SUCCESS) {
+ } else if (enable == Enable::ENABLED && status_view.GetStatus() != ErrorCode::SUCCESS) {
if (cs_requester_trackers_.count(connection_handle) == 0) {
log::error("Error code {} for connection_handle {}. No request tracker found.",
ErrorCodeText(status), connection_handle);
@@ -915,6 +922,14 @@ struct DistanceMeasurementManager::impl : bluetooth::hal::RangingHalCallback {
if (cs_requester_trackers_[connection_handle].retry_counter_for_cs_enable++ >=
kMaxRetryCounterForCsEnable) {
handle_cs_setup_failure(connection_handle, REASON_INTERNAL_ERROR);
+ } else {
+ cs_requester_trackers_[connection_handle].procedure_schedule_guard_alarm->Cancel();
+ log::info("schedule next procedure enable after {} ms",
+ cs_requester_trackers_[connection_handle].interval_ms);
+ cs_requester_trackers_[connection_handle].procedure_schedule_guard_alarm->Schedule(
+ common::Bind(&impl::send_le_cs_procedure_enable, common::Unretained(this),
+ connection_handle, Enable::ENABLED),
+ std::chrono::milliseconds(cs_requester_trackers_[connection_handle].interval_ms));
}
}
}
@@ -1233,25 +1248,8 @@ struct DistanceMeasurementManager::impl : bluetooth::hal::RangingHalCallback {
void on_cs_procedure_enable_complete(LeCsProcedureEnableCompleteView event_view) {
log::assert_that(event_view.IsValid(), "assert failed: event_view.IsValid()");
uint16_t connection_handle = event_view.GetConnectionHandle();
- log::debug("on cs procedure enabled complete");
- if (event_view.GetStatus() != ErrorCode::SUCCESS) {
- std::string error_code = ErrorCodeText(event_view.GetStatus());
- if (cs_requester_trackers_.count(connection_handle) == 0) {
- log::warn(
- "Received LeCsProcedureEnableCompleteView with error code {}, No request tracker "
- "found",
- error_code);
- handle_cs_setup_failure(connection_handle, REASON_INTERNAL_ERROR);
- return;
- }
- log::warn("Received LeCsProcedureEnableCompleteView with error code {}. Retry counter {}",
- error_code, cs_requester_trackers_[connection_handle].retry_counter_for_cs_enable);
- if (cs_requester_trackers_[connection_handle].retry_counter_for_cs_enable++ >=
- kMaxRetryCounterForCsEnable) {
- handle_cs_setup_failure(connection_handle, REASON_INTERNAL_ERROR);
- }
- return;
- }
+ log::debug("Procedure enabled, {}", event_view.ToString());
+
uint8_t config_id = event_view.GetConfigId();
CsTracker* live_tracker = nullptr;
@@ -1268,7 +1266,7 @@ struct DistanceMeasurementManager::impl : bluetooth::hal::RangingHalCallback {
live_tracker = get_live_tracker(connection_handle, config_id, valid_requester_states,
valid_responder_states);
if (live_tracker == nullptr) {
- log::error("no tracker is available for {}", connection_handle);
+ log::error("enable - no tracker is available for {}", connection_handle);
return;
}
if (live_tracker->used_config_id != config_id) {
@@ -1276,7 +1274,22 @@ struct DistanceMeasurementManager::impl : bluetooth::hal::RangingHalCallback {
live_tracker->used_config_id);
return;
}
- log::debug("Procedure enabled, {}", event_view.ToString());
+
+ if (live_tracker->local_start && event_view.GetStatus() != ErrorCode::SUCCESS) {
+ log::warn("Received LeCsProcedureEnableCompleteView with error code {}. Retry counter {}",
+ ErrorCodeText(event_view.GetStatus()), live_tracker->retry_counter_for_cs_enable);
+ if (live_tracker->retry_counter_for_cs_enable++ >= kMaxRetryCounterForCsEnable) {
+ handle_cs_setup_failure(connection_handle, REASON_INTERNAL_ERROR);
+ } else {
+ live_tracker->procedure_schedule_guard_alarm->Cancel();
+ log::info("schedule next procedure enable after {} ms", live_tracker->interval_ms);
+ live_tracker->procedure_schedule_guard_alarm->Schedule(
+ common::Bind(&impl::send_le_cs_procedure_enable, common::Unretained(this),
+ connection_handle, Enable::ENABLED),
+ std::chrono::milliseconds(live_tracker->interval_ms));
+ }
+ return;
+ }
live_tracker->state = CsTrackerState::STARTED;
live_tracker->selected_tx_power = event_view.GetSelectedTxPower();
live_tracker->n_procedure_count = event_view.GetProcedureCount();
@@ -1293,38 +1306,45 @@ struct DistanceMeasurementManager::impl : bluetooth::hal::RangingHalCallback {
if (live_tracker->n_procedure_count >= 1) {
live_tracker->procedure_schedule_guard_alarm->Cancel();
log::info("schedule next procedure enable after {} ms", schedule_interval);
- cs_requester_trackers_[connection_handle].procedure_schedule_guard_alarm->Schedule(
+ live_tracker->procedure_schedule_guard_alarm->Schedule(
common::Bind(&impl::send_le_cs_procedure_enable, common::Unretained(this),
connection_handle, Enable::ENABLED),
std::chrono::milliseconds(schedule_interval));
}
- }
- if (live_tracker->local_start && live_tracker->waiting_for_start_callback) {
- live_tracker->waiting_for_start_callback = false;
- distance_measurement_callbacks_->OnDistanceMeasurementStarted(live_tracker->address,
- METHOD_CS);
- }
- if (live_tracker->local_start && is_hal_v2()) {
- // reset the procedure sequence
- live_tracker->procedure_sequence_after_enable = -1;
- ranging_hal_->UpdateProcedureEnableConfig(connection_handle, event_view);
+ if (live_tracker->waiting_for_start_callback) {
+ live_tracker->waiting_for_start_callback = false;
+ distance_measurement_callbacks_->OnDistanceMeasurementStarted(live_tracker->address,
+ METHOD_CS);
+ }
+ if (is_hal_v2()) {
+ // reset the procedure sequence
+ live_tracker->procedure_sequence_after_enable = -1;
+ ranging_hal_->UpdateProcedureEnableConfig(connection_handle, event_view);
+ }
}
} else if (event_view.GetState() == Enable::DISABLED) {
- uint8_t valid_requester_states = static_cast<uint8_t>(CsTrackerState::STARTED);
- uint8_t valid_responder_states = static_cast<uint8_t>(CsTrackerState::STARTED);
- live_tracker = get_live_tracker(connection_handle, config_id, valid_requester_states,
- valid_responder_states);
- if (live_tracker == nullptr) {
- log::error("no tracker is available for {}", connection_handle);
- return;
+ if (event_view.GetStatus() == ErrorCode::SUCCESS) {
+ // local or remote host requested it.
+ uint8_t valid_requester_states = static_cast<uint8_t>(CsTrackerState::STARTED);
+ uint8_t valid_responder_states = static_cast<uint8_t>(CsTrackerState::STARTED);
+ live_tracker = get_live_tracker(connection_handle, config_id, valid_requester_states,
+ valid_responder_states);
+ if (live_tracker == nullptr) {
+ log::error("disable - no tracker is available for {}", connection_handle);
+ return;
+ }
+ reset_tracker_on_stopped(*live_tracker);
+ } else {
+ // work around, controller may send 'DISABLE' complete with error for 'ENABLE' command
+ auto req_it = cs_requester_trackers_.find(connection_handle);
+ if (req_it != cs_requester_trackers_.end() &&
+ req_it->second.state == CsTrackerState::WAIT_FOR_PROCEDURE_ENABLED &&
+ config_id == req_it->second.used_config_id) {
+ log::warn("expect ENABLE complete, bug got DISABLE complete.");
+ handle_cs_setup_failure(connection_handle, REASON_INTERNAL_ERROR);
+ }
}
- reset_tracker_on_stopped(*live_tracker);
- }
- // reset the procedure data list.
- std::vector<CsProcedureData>& data_list = live_tracker->procedure_data_list;
- while (!data_list.empty()) {
- data_list.erase(data_list.begin());
}
}
@@ -2618,17 +2638,17 @@ struct DistanceMeasurementManager::impl : bluetooth::hal::RangingHalCallback {
v1.insert(v1.end(), v2.begin(), v2.end());
}
- os::Handler* handler_;
- hal::RangingHal* ranging_hal_;
- hci::Controller* controller_;
- hci::HciLayer* hci_layer_;
- hci::AclManager* acl_manager_;
- hci::DistanceMeasurementInterface* distance_measurement_interface_;
+ os::Handler* handler_ = nullptr;
+ hal::RangingHal* ranging_hal_ = nullptr;
+ hci::Controller* controller_ = nullptr;
+ hci::HciLayer* hci_layer_ = nullptr;
+ hci::AclManager* acl_manager_ = nullptr;
+ hci::DistanceMeasurementInterface* distance_measurement_interface_ = nullptr;
std::unordered_map<Address, RSSITracker> rssi_trackers;
std::unordered_map<uint16_t, CsTracker> cs_requester_trackers_;
std::unordered_map<uint16_t, CsTracker> cs_responder_trackers_;
std::unordered_map<uint16_t, uint16_t> gatt_mtus_;
- DistanceMeasurementCallbacks* distance_measurement_callbacks_;
+ DistanceMeasurementCallbacks* distance_measurement_callbacks_ = nullptr;
CsOptionalSubfeaturesSupported cs_subfeature_supported_;
uint8_t num_antennas_supported_ = 0x01;
bool local_support_phase_based_ranging_ = false;
diff --git a/system/gd/hci/distance_measurement_manager.h b/system/gd/hci/distance_measurement_manager.h
index c0f3cae654..9d13e50cd1 100644
--- a/system/gd/hci/distance_measurement_manager.h
+++ b/system/gd/hci/distance_measurement_manager.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/system/gd/hci/distance_measurement_manager_mock.h b/system/gd/hci/distance_measurement_manager_mock.h
index 827c096670..ba9919af9e 100644
--- a/system/gd/hci/distance_measurement_manager_mock.h
+++ b/system/gd/hci/distance_measurement_manager_mock.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -31,12 +31,22 @@ struct DistanceMeasurementManager::impl : public bluetooth::hci::LeAddressManage
namespace testing {
class MockDistanceMeasurementCallbacks : public DistanceMeasurementCallbacks {
+public:
MOCK_METHOD(void, OnDistanceMeasurementStarted, (Address, DistanceMeasurementMethod));
MOCK_METHOD(void, OnDistanceMeasurementStopped,
(Address, DistanceMeasurementErrorCode, DistanceMeasurementMethod));
MOCK_METHOD(void, OnDistanceMeasurementResult,
(Address, uint32_t, uint32_t, int, int, int, int, uint64_t, int8_t, double,
DistanceMeasurementDetectedAttackLevel, double, DistanceMeasurementMethod));
+ MOCK_METHOD(void, OnRasFragmentReady,
+ (Address address, uint16_t procedure_counter, bool is_last,
+ std::vector<uint8_t> raw_data));
+ MOCK_METHOD(void, OnVendorSpecificCharacteristics,
+ (std::vector<hal::VendorSpecificCharacteristic> vendor_specific_characteristics));
+ MOCK_METHOD(void, OnVendorSpecificReply,
+ (Address address, std::vector<bluetooth::hal::VendorSpecificCharacteristic>
+ vendor_specific_characteristics));
+ MOCK_METHOD(void, OnHandleVendorSpecificReplyComplete, (Address address, bool success));
};
class MockDistanceMeasurementManager : public DistanceMeasurementManager {
diff --git a/system/gd/hci/distance_measurement_manager_test.cc b/system/gd/hci/distance_measurement_manager_test.cc
index b7f2abe8b3..35a629c53a 100644
--- a/system/gd/hci/distance_measurement_manager_test.cc
+++ b/system/gd/hci/distance_measurement_manager_test.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2025 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,17 +21,34 @@
#include <gmock/gmock.h>
#include <gtest/gtest.h>
+#include "common/bind.h"
+#include "common/strings.h"
#include "hal/ranging_hal.h"
#include "hal/ranging_hal_mock.h"
#include "hci/acl_manager_mock.h"
+#include "hci/address.h"
#include "hci/controller.h"
#include "hci/controller_mock.h"
+#include "hci/distance_measurement_manager_mock.h"
#include "hci/hci_layer.h"
#include "hci/hci_layer_fake.h"
#include "module.h"
+#include "os/fake_timer/fake_timerfd.h"
+#include "packet/packet_view.h"
+#include "ras/ras_packets.h"
+using bluetooth::os::fake_timer::fake_timerfd_advance;
+using bluetooth::os::fake_timer::fake_timerfd_reset;
+using testing::_;
+using testing::AtLeast;
using testing::Return;
+namespace {
+static constexpr auto kTimeout = std::chrono::seconds(1);
+static constexpr uint8_t kMaxRetryCounterForCreateConfig = 0x03;
+static constexpr uint8_t kMaxRetryCounterForCsEnable = 0x03;
+}
+
namespace bluetooth {
namespace hci {
namespace {
@@ -43,12 +60,113 @@ protected:
};
class TestAclManager : public testing::MockAclManager {
+public:
+ void AddDeviceToRelaxedConnectionIntervalList(const Address /*address*/) override {}
+
protected:
void Start() override {}
void Stop() override {}
void ListDependencies(ModuleList* /* list */) const override {}
};
+struct CsReadCapabilitiesCompleteEvent {
+ ErrorCode error_code = ErrorCode::SUCCESS;
+ uint8_t num_config_supported = 4;
+ uint16_t max_consecutive_procedures_supported = 0;
+ uint8_t num_antennas_supported = 2;
+ uint8_t max_antenna_paths_supported = 4;
+ CsRoleSupported roles_supported = {/*initiator=*/1, /*reflector=*/1};
+ unsigned char modes_supported = {/*mode_3=*/1};
+ CsRttCapability rtt_capability = {/*rtt_aa_only_n=*/1, /*rtt_sounding_n=*/1,
+ /*rtt_random_payload_n=*/1};
+ uint8_t rtt_aa_only_n = 1;
+ uint8_t rtt_sounding_n = 1;
+ uint8_t rtt_random_payload_n = 1;
+ CsOptionalNadmSoundingCapability nadm_sounding_capability = {
+ /*normalized_attack_detector_metric=*/1};
+ CsOptionalNadmRandomCapability nadm_random_capability = {/*normalized_attack_detector_metric=*/1};
+ CsOptionalCsSyncPhysSupported cs_sync_phys_supported = {/*le_2m_phy=*/1, /*le_2m_2bt_phy=*/0};
+ CsOptionalSubfeaturesSupported subfeatures_supported = {/*no_frequency_actuation_error=*/1,
+ /*channel_selection_algorithm=*/1,
+ /*phase_based_ranging=*/1};
+ CsOptionalTIp1TimesSupported t_ip1_times_supported = {
+ /*support_10_microsecond=*/1, /*support_20_microsecond=*/1,
+ /*support_30_microsecond=*/1, /*support_40_microsecond=*/1,
+ /*support_50_microsecond=*/1, /*support_60_microsecond=*/1,
+ /*support_80_microsecond=*/1};
+ CsOptionalTIp2TimesSupported t_ip2_times_supported = {
+ /*support_10_microsecond=*/1, /*support_20_microsecond=*/1,
+ /*support_30_microsecond=*/1,
+ /*support_40_microsecond=*/1, /*support_50_microsecond=*/1,
+ /*support_60_microsecond=*/1, /*support_80_microsecond=*/1};
+ CsOptionalTFcsTimesSupported t_fcs_times_supported = {
+ /*support_15_microsecond=*/1, /*support_20_microsecond=*/1,
+ /*support_30_microsecond=*/1, /*support_40_microsecond=*/1,
+ /*support_50_microsecond=*/1,
+ /*support_60_microsecond=*/1, /*support_80_microsecond=*/1,
+ /*support_100_microsecond=*/1,
+ /*support_120_microsecond=*/1};
+ CsOptionalTPmTimesSupported t_pm_times_supported = {/*support_10_microsecond=*/1,
+ /*support_20_microsecond=*/1};
+ uint8_t t_sw_time_supported = 1;
+ uint8_t tx_snr_capability = 1;
+};
+
+struct CsConfigCompleteEvent {
+ ErrorCode status = ErrorCode::SUCCESS;
+ uint8_t config_id = 0;
+ CsAction action = CsAction::CONFIG_CREATED;
+ CsMainModeType main_mode_type = CsMainModeType::MODE_2;
+ CsSubModeType sub_mode_type = CsSubModeType::UNUSED;
+ uint8_t min_main_mode_steps = 3; // 0x02 to 0xFF
+ uint8_t max_main_mode_steps = 100; // 0x02 to 0xFF
+ uint8_t main_mode_repetition = 0; // 0x00 to 0x03
+ uint8_t mode_0_steps = 1; // 0x01 to 0x03
+ CsRole cs_role = CsRole::INITIATOR;
+ CsRttType rtt_type = CsRttType::RTT_AA_ONLY;
+ CsSyncPhy sync_phy = CsSyncPhy::LE_2M_PHY;
+ std::array<uint8_t, 10> channel_map = GetChannelMap("1FFFFFFFFFFFFC7FFFFC");
+ uint8_t channel_map_repetition = 1; // 0x01 to 0xFF
+ CsChannelSelectionType channel_selection_type = CsChannelSelectionType::TYPE_3C;
+ CsCh3cShape ch3c_shape = CsCh3cShape::HAT_SHAPE;
+ uint8_t ch3c_jump = 2; // 0x02 to 0x08
+ uint8_t t_ip1_time = 0x0A; // 0x0A, 0x14, 0x1E, 0x28, 0x32, 0x3C, 0x50, or 0x91
+ uint8_t t_ip2_time = 0x0A; // 0x0A, 0x14, 0x1E, 0x28, 0x32, 0x3C, 0x50, or 0x91
+ uint8_t t_fcs_time = 0x0F; // 0x0F, 0x14, 0x1E, 0x28, 0x32, 0x3C, 0x50, 0x64, 0x78, or 0x96
+ uint8_t t_pm_time = 0x0A; // 0x0A, 0x14, or 0x28
+
+ static const std::array<uint8_t, 10> GetChannelMap(const std::string& hex_string) {
+ assert(hex_stinrg.length() == 20);
+ auto channel_vector = common::FromHexString(hex_string);
+ std::array<uint8_t, 10> channel_map{};
+ std::copy(channel_vector->begin(), channel_vector->end(), channel_map.begin());
+ std::reverse(channel_map.begin(), channel_map.end());
+ return channel_map;
+ }
+};
+
+struct CsProcedureEnableCompleteEvent {
+ ErrorCode status = ErrorCode::SUCCESS;
+ uint8_t config_id = 0;
+ uint8_t tone_antenna_config_selection = 0;
+ uint8_t selected_tx_power = 0; // -127 to 20 dBm
+ uint32_t subevent_len = 2500; // 1250us to 4s
+ uint8_t subevents_per_event = 1; // 0x01 to 0x20
+ uint16_t subevent_interval = 1; // N x 0.625ms
+ uint16_t event_interval = 0; // number of acl conn interval
+ uint16_t procedure_interval = 2; // number of acl conn interval
+ uint16_t procedure_count = 5; // 0x0001 to 0xFFFF
+ uint16_t max_procedure_len = 10; // N x 0.625 ms
+};
+
+struct StartMeasurementParameters {
+ Address remote_address = Address::FromString("12:34:56:78:9a:bc").value();
+ uint16_t connection_handle = 64;
+ Role local_hci_role = Role::CENTRAL;
+ uint16_t interval = 200; // 200ms
+ DistanceMeasurementMethod method = DistanceMeasurementMethod::METHOD_CS;
+};
+
class DistanceMeasurementManagerTest : public ::testing::Test {
protected:
void SetUp() override {
@@ -65,10 +183,13 @@ protected:
ASSERT_NE(client_handler_, nullptr);
EXPECT_CALL(*mock_controller_, SupportsBleChannelSounding()).WillOnce(Return(true));
- EXPECT_CALL(*mock_ranging_hal_, IsBound()).WillOnce(Return(true));
+ EXPECT_CALL(*mock_ranging_hal_, IsBound()).Times(AtLeast(1)).WillRepeatedly(Return(true));
+ EXPECT_CALL(*mock_ranging_hal_, GetRangingHalVersion).WillRepeatedly(Return(hal::V_2));
handler_ = fake_registry_.GetTestHandler();
dm_manager_ = fake_registry_.Start<DistanceMeasurementManager>(&thread_, handler_);
+
+ dm_manager_->RegisterDistanceMeasurementCallbacks(&mock_dm_callbacks_);
}
void TearDown() override {
@@ -77,6 +198,178 @@ protected:
fake_registry_.StopAll();
}
+ std::future<void> GetDmSessionFuture() {
+ log::assert_that(dm_session_promise_ == nullptr, "Promises promises ... Only one at a time");
+ dm_session_promise_ = std::make_unique<std::promise<void>>();
+ return dm_session_promise_->get_future();
+ }
+
+ std::future<void> fake_timer_advance(uint64_t ms) {
+ std::promise<void> promise;
+ auto future = promise.get_future();
+ handler_->Post(common::BindOnce(
+ [](std::promise<void> promise, uint64_t ms) {
+ fake_timerfd_advance(ms);
+ promise.set_value();
+ },
+ common::Passed(std::move(promise)), ms));
+
+ return future;
+ }
+
+ void sync_client_handler() {
+ log::assert_that(thread_.GetReactor()->WaitForIdle(kTimeout),
+ "assert failed: thread_.GetReactor()->WaitForIdle(kTimeout)");
+ }
+
+ static std::unique_ptr<LeCsReadLocalSupportedCapabilitiesCompleteBuilder>
+ GetLocalSupportedCapabilitiesCompleteEvent(
+ const CsReadCapabilitiesCompleteEvent& cs_cap_complete_event) {
+ return LeCsReadLocalSupportedCapabilitiesCompleteBuilder::Create(
+ /*num_hci_command_packets=*/0xFF, cs_cap_complete_event.error_code,
+ cs_cap_complete_event.num_config_supported,
+ cs_cap_complete_event.max_consecutive_procedures_supported,
+ cs_cap_complete_event.num_antennas_supported,
+ cs_cap_complete_event.max_antenna_paths_supported,
+ cs_cap_complete_event.roles_supported, cs_cap_complete_event.modes_supported,
+ cs_cap_complete_event.rtt_capability, cs_cap_complete_event.rtt_aa_only_n,
+ cs_cap_complete_event.rtt_sounding_n, cs_cap_complete_event.rtt_random_payload_n,
+ cs_cap_complete_event.nadm_sounding_capability,
+ cs_cap_complete_event.nadm_random_capability,
+ cs_cap_complete_event.cs_sync_phys_supported,
+ cs_cap_complete_event.subfeatures_supported,
+ cs_cap_complete_event.t_ip1_times_supported,
+ cs_cap_complete_event.t_ip2_times_supported,
+ cs_cap_complete_event.t_fcs_times_supported, cs_cap_complete_event.t_pm_times_supported,
+ cs_cap_complete_event.t_sw_time_supported, cs_cap_complete_event.tx_snr_capability);
+ }
+
+ static std::unique_ptr<LeCsReadRemoteSupportedCapabilitiesCompleteBuilder>
+ GetRemoteSupportedCapabilitiesCompleteEvent(
+ uint16_t connection_handle,
+ const CsReadCapabilitiesCompleteEvent& cs_cap_complete_event) {
+ return LeCsReadRemoteSupportedCapabilitiesCompleteBuilder::Create(
+ cs_cap_complete_event.error_code, connection_handle,
+ cs_cap_complete_event.num_config_supported,
+ cs_cap_complete_event.max_consecutive_procedures_supported,
+ cs_cap_complete_event.num_antennas_supported,
+ cs_cap_complete_event.max_antenna_paths_supported,
+ cs_cap_complete_event.roles_supported, cs_cap_complete_event.modes_supported,
+ cs_cap_complete_event.rtt_capability, cs_cap_complete_event.rtt_aa_only_n,
+ cs_cap_complete_event.rtt_sounding_n, cs_cap_complete_event.rtt_random_payload_n,
+ cs_cap_complete_event.nadm_sounding_capability,
+ cs_cap_complete_event.nadm_random_capability,
+ cs_cap_complete_event.cs_sync_phys_supported,
+ cs_cap_complete_event.subfeatures_supported,
+ cs_cap_complete_event.t_ip1_times_supported,
+ cs_cap_complete_event.t_ip2_times_supported,
+ cs_cap_complete_event.t_fcs_times_supported, cs_cap_complete_event.t_pm_times_supported,
+ cs_cap_complete_event.t_sw_time_supported, cs_cap_complete_event.tx_snr_capability);
+ }
+
+ static std::unique_ptr<LeCsConfigCompleteBuilder> GetConfigCompleteEvent(
+ uint16_t connection_handle, CsConfigCompleteEvent complete_event) {
+ return LeCsConfigCompleteBuilder::Create(
+ complete_event.status, connection_handle, complete_event.config_id,
+ complete_event.action, complete_event.main_mode_type, complete_event.sub_mode_type,
+ complete_event.min_main_mode_steps, complete_event.max_main_mode_steps,
+ complete_event.main_mode_repetition, complete_event.mode_0_steps,
+ complete_event.cs_role, complete_event.rtt_type, complete_event.sync_phy,
+ complete_event.channel_map, complete_event.channel_map_repetition,
+ complete_event.channel_selection_type, complete_event.ch3c_shape,
+ complete_event.ch3c_jump, complete_event.t_ip1_time, complete_event.t_ip2_time,
+ complete_event.t_fcs_time, complete_event.t_pm_time);
+ }
+
+ static std::unique_ptr<LeCsProcedureEnableCompleteBuilder> GetProcedureEnableCompleteEvent(
+ uint16_t connection_handle, Enable enable,
+ CsProcedureEnableCompleteEvent complete_event) {
+ return LeCsProcedureEnableCompleteBuilder::Create(
+ complete_event.status, connection_handle, complete_event.config_id, enable,
+ complete_event.tone_antenna_config_selection, complete_event.selected_tx_power,
+ complete_event.subevent_len, complete_event.subevents_per_event,
+ complete_event.subevent_interval, complete_event.event_interval,
+ complete_event.procedure_interval, complete_event.procedure_count,
+ complete_event.max_procedure_len);
+ }
+
+ void StartMeasurement(const StartMeasurementParameters& params) {
+ dm_manager_->StartDistanceMeasurement(params.remote_address, params.connection_handle,
+ params.local_hci_role, params.interval, params.method);
+ }
+
+ void ReceivedReadLocalCapabilitiesComplete() {
+ CsReadCapabilitiesCompleteEvent read_cs_complete_event;
+ test_hci_layer_->IncomingEvent(
+ GetLocalSupportedCapabilitiesCompleteEvent(read_cs_complete_event));
+ }
+
+ void StartMeasurementTillRasConnectedEvent(const StartMeasurementParameters& params) {
+ ReceivedReadLocalCapabilitiesComplete();
+ EXPECT_CALL(*mock_ranging_hal_, OpenSession(_, _, _))
+ .WillOnce([this](uint16_t connection_handle, uint16_t /*att_handle*/,
+ const std::vector<hal::VendorSpecificCharacteristic>&
+ vendor_specific_data) {
+ mock_ranging_hal_->GetRangingHalCallback()->OnOpened(connection_handle,
+ vendor_specific_data);
+ });
+ StartMeasurement(params);
+ dm_manager_->HandleRasClientConnectedEvent(
+ params.remote_address, params.connection_handle,
+ /*att_handle=*/0,
+ /*vendor_specific_data=*/std::vector<hal::VendorSpecificCharacteristic>(),
+ /*conn_interval=*/24);
+ }
+
+ void StartMeasurementTillReadRemoteCaps(const StartMeasurementParameters& params) {
+ StartMeasurementTillRasConnectedEvent(params);
+
+ test_hci_layer_->GetCommand(OpCode::LE_CS_READ_REMOTE_SUPPORTED_CAPABILITIES);
+ CsReadCapabilitiesCompleteEvent read_cs_complete_event;
+ test_hci_layer_->IncomingEvent(LeCsReadRemoteSupportedCapabilitiesStatusBuilder::Create(
+ /*status=*/ErrorCode::SUCCESS,
+ /*num_hci_command_packets=*/0xFF));
+ test_hci_layer_->IncomingLeMetaEvent(GetRemoteSupportedCapabilitiesCompleteEvent(
+ params.connection_handle, read_cs_complete_event));
+
+ test_hci_layer_->GetCommand(OpCode::LE_CS_SET_DEFAULT_SETTINGS);
+ test_hci_layer_->IncomingEvent(LeCsSetDefaultSettingsCompleteBuilder::Create(
+ /*num_hci_command_packets=*/static_cast<uint8_t>(0xEE), ErrorCode::SUCCESS,
+ params.connection_handle));
+ }
+
+ void StartMeasurementTillCreateConfig(const StartMeasurementParameters& params) {
+ StartMeasurementTillReadRemoteCaps(params);
+
+ CsConfigCompleteEvent cs_config_complete_event;
+ test_hci_layer_->GetCommand(OpCode::LE_CS_CREATE_CONFIG);
+ test_hci_layer_->IncomingEvent(LeCsCreateConfigStatusBuilder::Create(
+ /*status=*/ErrorCode::SUCCESS,
+ /*num_hci_command_packets=*/0xFF));
+ test_hci_layer_->IncomingLeMetaEvent(
+ GetConfigCompleteEvent(params.connection_handle, cs_config_complete_event));
+ }
+
+ void StartMeasurementTillSecurityEnable(const StartMeasurementParameters& params) {
+ StartMeasurementTillCreateConfig(params);
+
+ test_hci_layer_->GetCommand(OpCode::LE_CS_SECURITY_ENABLE);
+ test_hci_layer_->IncomingEvent(LeCsSecurityEnableStatusBuilder::Create(
+ /*status=*/ErrorCode::SUCCESS,
+ /*num_hci_command_packets=*/0xFF));
+ test_hci_layer_->IncomingLeMetaEvent(LeCsSecurityEnableCompleteBuilder::Create(
+ ErrorCode::SUCCESS, params.connection_handle));
+ }
+
+ void StartMeasurementTillSetProcedureParameters(const StartMeasurementParameters& params) {
+ StartMeasurementTillSecurityEnable(params);
+
+ test_hci_layer_->GetCommand(OpCode::LE_CS_SET_PROCEDURE_PARAMETERS);
+ test_hci_layer_->IncomingEvent(LeCsSetProcedureParametersCompleteBuilder::Create(
+ /*num_hci_command_packets=*/static_cast<uint8_t>(0xEE), ErrorCode::SUCCESS,
+ params.connection_handle));
+ }
+
protected:
TestModuleRegistry fake_registry_;
HciLayerFake* test_hci_layer_ = nullptr;
@@ -88,12 +381,249 @@ protected:
os::Handler* handler_ = nullptr;
DistanceMeasurementManager* dm_manager_ = nullptr;
+ testing::MockDistanceMeasurementCallbacks mock_dm_callbacks_;
+ std::unique_ptr<std::promise<void>> dm_session_promise_;
};
TEST_F(DistanceMeasurementManagerTest, setup_teardown) {
EXPECT_NE(mock_ranging_hal_->GetRangingHalCallback(), nullptr);
}
+TEST_F(DistanceMeasurementManagerTest, fail_read_local_cs_capabilities) {
+ StartMeasurementParameters params;
+ auto dm_session_future = GetDmSessionFuture();
+ EXPECT_CALL(mock_dm_callbacks_,
+ OnDistanceMeasurementStopped(params.remote_address,
+ DistanceMeasurementErrorCode::REASON_INTERNAL_ERROR,
+ DistanceMeasurementMethod::METHOD_CS))
+ .WillOnce([this](const Address& /*address*/, DistanceMeasurementErrorCode /*error_code*/,
+ DistanceMeasurementMethod /*method*/) {
+ ASSERT_NE(dm_session_promise_, nullptr);
+ dm_session_promise_->set_value();
+ dm_session_promise_.reset();
+ });
+
+ CsReadCapabilitiesCompleteEvent read_cs_complete_event;
+ read_cs_complete_event.error_code = ErrorCode::COMMAND_DISALLOWED;
+ test_hci_layer_->IncomingEvent(
+ GetLocalSupportedCapabilitiesCompleteEvent(read_cs_complete_event));
+
+ StartMeasurement(params);
+
+ dm_session_future.wait_for(kTimeout);
+ sync_client_handler();
+}
+
+TEST_F(DistanceMeasurementManagerTest, ras_remote_not_support) {
+ ReceivedReadLocalCapabilitiesComplete();
+ StartMeasurementParameters params;
+ auto dm_session_future = GetDmSessionFuture();
+ EXPECT_CALL(mock_dm_callbacks_,
+ OnDistanceMeasurementStopped(
+ params.remote_address,
+ DistanceMeasurementErrorCode::REASON_FEATURE_NOT_SUPPORTED_REMOTE,
+ DistanceMeasurementMethod::METHOD_CS))
+ .WillOnce([this](const Address& /*address*/, DistanceMeasurementErrorCode /*error_code*/,
+ DistanceMeasurementMethod /*method*/) {
+ ASSERT_NE(dm_session_promise_, nullptr);
+ dm_session_promise_->set_value();
+ dm_session_promise_.reset();
+ });
+
+ StartMeasurement(params);
+ dm_manager_->HandleRasClientDisconnectedEvent(params.remote_address,
+ ras::RasDisconnectReason::SERVER_NOT_AVAILABLE);
+
+ dm_session_future.wait_for(kTimeout);
+ sync_client_handler();
+}
+
+TEST_F(DistanceMeasurementManagerTest, error_read_remote_cs_caps_command) {
+ auto dm_session_future = GetDmSessionFuture();
+ StartMeasurementParameters params;
+ StartMeasurementTillRasConnectedEvent(params);
+
+ EXPECT_CALL(mock_dm_callbacks_,
+ OnDistanceMeasurementStopped(params.remote_address,
+ DistanceMeasurementErrorCode::REASON_INTERNAL_ERROR,
+ DistanceMeasurementMethod::METHOD_CS))
+ .WillOnce([this](const Address& /*address*/, DistanceMeasurementErrorCode /*error_code*/,
+ DistanceMeasurementMethod /*method*/) {
+ ASSERT_NE(dm_session_promise_, nullptr);
+ dm_session_promise_->set_value();
+ dm_session_promise_.reset();
+ });
+
+ test_hci_layer_->GetCommand(OpCode::LE_CS_READ_REMOTE_SUPPORTED_CAPABILITIES);
+ test_hci_layer_->IncomingEvent(LeCsReadRemoteSupportedCapabilitiesStatusBuilder::Create(
+ /*status=*/ErrorCode::COMMAND_DISALLOWED,
+ /*num_hci_command_packets=*/0xff));
+ sync_client_handler();
+}
+
+TEST_F(DistanceMeasurementManagerTest, fail_read_remote_cs_caps_complete) {
+ auto dm_session_future = GetDmSessionFuture();
+ StartMeasurementParameters params;
+ StartMeasurementTillRasConnectedEvent(params);
+
+ EXPECT_CALL(mock_dm_callbacks_,
+ OnDistanceMeasurementStopped(params.remote_address,
+ DistanceMeasurementErrorCode::REASON_INTERNAL_ERROR,
+ DistanceMeasurementMethod::METHOD_CS))
+ .WillOnce([this](const Address& /*address*/, DistanceMeasurementErrorCode /*error_code*/,
+ DistanceMeasurementMethod /*method*/) {
+ ASSERT_NE(dm_session_promise_, nullptr);
+ dm_session_promise_->set_value();
+ dm_session_promise_.reset();
+ });
+
+ test_hci_layer_->GetCommand(OpCode::LE_CS_READ_REMOTE_SUPPORTED_CAPABILITIES);
+ CsReadCapabilitiesCompleteEvent read_cs_complete_event;
+ read_cs_complete_event.error_code = ErrorCode::COMMAND_DISALLOWED;
+ test_hci_layer_->IncomingLeMetaEvent(GetRemoteSupportedCapabilitiesCompleteEvent(
+ params.connection_handle, read_cs_complete_event));
+ sync_client_handler();
+}
+
+TEST_F(DistanceMeasurementManagerTest, error_create_config_command) {
+ auto dm_session_future = GetDmSessionFuture();
+ StartMeasurementParameters params;
+ StartMeasurementTillReadRemoteCaps(params);
+
+ EXPECT_CALL(mock_dm_callbacks_,
+ OnDistanceMeasurementStopped(params.remote_address,
+ DistanceMeasurementErrorCode::REASON_INTERNAL_ERROR,
+ DistanceMeasurementMethod::METHOD_CS))
+ .WillOnce([this](const Address& /*address*/, DistanceMeasurementErrorCode /*error_code*/,
+ DistanceMeasurementMethod /*method*/) {
+ ASSERT_NE(dm_session_promise_, nullptr);
+ dm_session_promise_->set_value();
+ dm_session_promise_.reset();
+ });
+
+ test_hci_layer_->GetCommand(OpCode::LE_CS_CREATE_CONFIG);
+ test_hci_layer_->IncomingEvent(LeCsCreateConfigStatusBuilder::Create(
+ /*status=*/ErrorCode::COMMAND_DISALLOWED,
+ /*num_hci_command_packets=*/0xff));
+ sync_client_handler();
+}
+
+TEST_F(DistanceMeasurementManagerTest, fail_create_config_complete) {
+ auto dm_session_future = GetDmSessionFuture();
+ StartMeasurementParameters params;
+ StartMeasurementTillReadRemoteCaps(params);
+
+ EXPECT_CALL(mock_dm_callbacks_,
+ OnDistanceMeasurementStopped(params.remote_address,
+ DistanceMeasurementErrorCode::REASON_INTERNAL_ERROR,
+ DistanceMeasurementMethod::METHOD_CS))
+ .WillOnce([this](const Address& /*address*/, DistanceMeasurementErrorCode /*error_code*/,
+ DistanceMeasurementMethod /*method*/) {
+ ASSERT_NE(dm_session_promise_, nullptr);
+ dm_session_promise_->set_value();
+ dm_session_promise_.reset();
+ });
+
+ CsConfigCompleteEvent cs_config_complete_event;
+ cs_config_complete_event.status = ErrorCode::COMMAND_DISALLOWED;
+ for (int i = 0; i <= kMaxRetryCounterForCreateConfig; i++) {
+ test_hci_layer_->GetCommand(OpCode::LE_CS_CREATE_CONFIG);
+ test_hci_layer_->IncomingLeMetaEvent(
+ GetConfigCompleteEvent(params.connection_handle, cs_config_complete_event));
+ }
+ sync_client_handler();
+}
+
+TEST_F(DistanceMeasurementManagerTest, retry_fail_procedure_enable_command) {
+ auto dm_session_future = GetDmSessionFuture();
+ StartMeasurementParameters params;
+ StartMeasurementTillSetProcedureParameters(params);
+
+ EXPECT_CALL(mock_dm_callbacks_,
+ OnDistanceMeasurementStopped(params.remote_address,
+ DistanceMeasurementErrorCode::REASON_INTERNAL_ERROR,
+ DistanceMeasurementMethod::METHOD_CS))
+ .WillOnce([this](const Address& /*address*/, DistanceMeasurementErrorCode /*error_code*/,
+ DistanceMeasurementMethod /*method*/) {
+ ASSERT_NE(dm_session_promise_, nullptr);
+ dm_session_promise_->set_value();
+ dm_session_promise_.reset();
+ });
+
+ for (int i = 0; i <= kMaxRetryCounterForCsEnable; i++) {
+ test_hci_layer_->GetCommand(OpCode::LE_CS_PROCEDURE_ENABLE);
+ test_hci_layer_->IncomingEvent(LeCsProcedureEnableStatusBuilder::Create(
+ /*status=*/ErrorCode::COMMAND_DISALLOWED,
+ /*num_hci_command_packets=*/0xff));
+ auto future = fake_timer_advance(params.interval + 10);
+ future.wait_for(kTimeout);
+ sync_client_handler();
+ }
+ fake_timerfd_reset();
+ sync_client_handler();
+}
+
+TEST_F(DistanceMeasurementManagerTest, retry_fail_procedure_enable_complete) {
+ auto dm_session_future = GetDmSessionFuture();
+ StartMeasurementParameters params;
+ StartMeasurementTillSetProcedureParameters(params);
+
+ EXPECT_CALL(mock_dm_callbacks_,
+ OnDistanceMeasurementStopped(params.remote_address,
+ DistanceMeasurementErrorCode::REASON_INTERNAL_ERROR,
+ DistanceMeasurementMethod::METHOD_CS))
+ .WillOnce([this](const Address& /*address*/, DistanceMeasurementErrorCode /*error_code*/,
+ DistanceMeasurementMethod /*method*/) {
+ ASSERT_NE(dm_session_promise_, nullptr);
+ dm_session_promise_->set_value();
+ dm_session_promise_.reset();
+ });
+
+ CsProcedureEnableCompleteEvent complete_event;
+ complete_event.status = ErrorCode::LINK_LAYER_COLLISION;
+ for (int i = 0; i <= kMaxRetryCounterForCsEnable; i++) {
+ test_hci_layer_->GetCommand(OpCode::LE_CS_PROCEDURE_ENABLE);
+ test_hci_layer_->IncomingEvent(LeCsProcedureEnableStatusBuilder::Create(
+ /*status=*/ErrorCode::SUCCESS,
+ /*num_hci_command_packets=*/0xff));
+ test_hci_layer_->IncomingLeMetaEvent(GetProcedureEnableCompleteEvent(
+ params.connection_handle, Enable::ENABLED, complete_event));
+ auto future = fake_timer_advance(params.interval + 10);
+ future.wait_for(kTimeout);
+ sync_client_handler();
+ }
+ fake_timerfd_reset();
+ sync_client_handler();
+}
+
+TEST_F(DistanceMeasurementManagerTest, unexpected_procedure_enable_complete_as_disable) {
+ auto dm_session_future = GetDmSessionFuture();
+ StartMeasurementParameters params;
+ StartMeasurementTillSetProcedureParameters(params);
+
+ EXPECT_CALL(mock_dm_callbacks_,
+ OnDistanceMeasurementStopped(params.remote_address,
+ DistanceMeasurementErrorCode::REASON_INTERNAL_ERROR,
+ DistanceMeasurementMethod::METHOD_CS))
+ .WillOnce([this](const Address& /*address*/, DistanceMeasurementErrorCode /*error_code*/,
+ DistanceMeasurementMethod /*method*/) {
+ ASSERT_NE(dm_session_promise_, nullptr);
+ dm_session_promise_->set_value();
+ dm_session_promise_.reset();
+ });
+
+ test_hci_layer_->GetCommand(OpCode::LE_CS_PROCEDURE_ENABLE);
+ test_hci_layer_->IncomingEvent(LeCsProcedureEnableStatusBuilder::Create(
+ /*status=*/ErrorCode::SUCCESS,
+ /*num_hci_command_packets=*/0xff));
+ CsProcedureEnableCompleteEvent complete_event;
+ complete_event.status = ErrorCode::LINK_LAYER_COLLISION;
+ test_hci_layer_->IncomingLeMetaEvent(GetProcedureEnableCompleteEvent(
+ params.connection_handle, Enable::DISABLED, complete_event));
+
+ sync_client_handler();
+}
+
} // namespace
} // namespace hci
} // namespace bluetooth
diff --git a/system/gd/hci/enum_helper.h b/system/gd/hci/enum_helper.h
index 43ac2f92a1..ad97c318e5 100644
--- a/system/gd/hci/enum_helper.h
+++ b/system/gd/hci/enum_helper.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/hci/event_checkers.h b/system/gd/hci/event_checkers.h
index a484f5752e..8263f238df 100644
--- a/system/gd/hci/event_checkers.h
+++ b/system/gd/hci/event_checkers.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/hci/fuzz/acl_manager_fuzz_test.cc b/system/gd/hci/fuzz/acl_manager_fuzz_test.cc
index d9c039415c..6c98e82168 100644
--- a/system/gd/hci/fuzz/acl_manager_fuzz_test.cc
+++ b/system/gd/hci/fuzz/acl_manager_fuzz_test.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/hci/fuzz/fuzz_hci_layer.cc b/system/gd/hci/fuzz/fuzz_hci_layer.cc
index 64115ec253..d665655bd3 100644
--- a/system/gd/hci/fuzz/fuzz_hci_layer.cc
+++ b/system/gd/hci/fuzz/fuzz_hci_layer.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/hci/fuzz/fuzz_hci_layer.h b/system/gd/hci/fuzz/fuzz_hci_layer.h
index d4a69c114e..59a09acfe2 100644
--- a/system/gd/hci/fuzz/fuzz_hci_layer.h
+++ b/system/gd/hci/fuzz/fuzz_hci_layer.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/hci/fuzz/hci_layer_fuzz_client.cc b/system/gd/hci/fuzz/hci_layer_fuzz_client.cc
index 6ca1b15f99..a76770dd70 100644
--- a/system/gd/hci/fuzz/hci_layer_fuzz_client.cc
+++ b/system/gd/hci/fuzz/hci_layer_fuzz_client.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/hci/fuzz/hci_layer_fuzz_client.h b/system/gd/hci/fuzz/hci_layer_fuzz_client.h
index 3f9942c48a..3a62de2890 100644
--- a/system/gd/hci/fuzz/hci_layer_fuzz_client.h
+++ b/system/gd/hci/fuzz/hci_layer_fuzz_client.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/hci/fuzz/hci_layer_fuzz_test.cc b/system/gd/hci/fuzz/hci_layer_fuzz_test.cc
index 1fed31e882..3f362879f5 100644
--- a/system/gd/hci/fuzz/hci_layer_fuzz_test.cc
+++ b/system/gd/hci/fuzz/hci_layer_fuzz_test.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/hci/fuzz/status_vs_complete_commands.cc b/system/gd/hci/fuzz/status_vs_complete_commands.cc
index c4cc72ca73..8c21cdeeec 100644
--- a/system/gd/hci/fuzz/status_vs_complete_commands.cc
+++ b/system/gd/hci/fuzz/status_vs_complete_commands.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/hci/fuzz/status_vs_complete_commands.h b/system/gd/hci/fuzz/status_vs_complete_commands.h
index 57cb9c1174..c2831f2819 100644
--- a/system/gd/hci/fuzz/status_vs_complete_commands.h
+++ b/system/gd/hci/fuzz/status_vs_complete_commands.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/hci/hci_interface.h b/system/gd/hci/hci_interface.h
index 46c5f400bd..677dead98e 100644
--- a/system/gd/hci/hci_interface.h
+++ b/system/gd/hci/hci_interface.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 The Android Open Source Project
+ * Copyright (C) 2024 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.
diff --git a/system/gd/hci/hci_layer.cc b/system/gd/hci/hci_layer.cc
index fd3d4ff278..da370a7564 100644
--- a/system/gd/hci/hci_layer.cc
+++ b/system/gd/hci/hci_layer.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
@@ -64,6 +64,11 @@ using std::unique_ptr;
static std::recursive_mutex life_cycle_guard;
static bool life_cycle_stopped = true;
+#ifdef TARGET_FLOSS
+// Signal to indicate the controller needs to be reset.
+const int SIG_RESET_CTRL = SIGUSR1;
+#endif
+
static std::chrono::milliseconds getHciTimeoutMs() {
static auto sHciTimeoutMs = std::chrono::milliseconds(bluetooth::os::GetSystemPropertyUint32Base(
"bluetooth.hci.timeout_milliseconds", HciLayer::kHciTimeoutMs.count()));
@@ -296,12 +301,18 @@ struct HciLayer::impl {
void on_hci_timeout(OpCode op_code) {
#ifdef TARGET_FLOSS
+ std::unique_lock<std::recursive_mutex> lock(life_cycle_guard);
+ if (life_cycle_stopped) {
+ return;
+ }
+
log::warn("Ignoring the timeouted HCI command {}.", OpCodeText(op_code));
- // Terminate the process to trigger controller reset, also mark the controller
- // is broken to prevent further error while terminating.
- auto hal = module_.GetDependency<hal::HciHal>();
- hal->markControllerBroken();
- kill(getpid(), SIGTERM);
+
+ // Terminate the process to trigger controller reset, also stop sending and
+ // processing any incoming packet immediately to prevent further error
+ // while terminating.
+ module_.LifeCycleStop();
+ kill(getpid(), SIG_RESET_CTRL);
return;
#endif
@@ -507,12 +518,11 @@ struct HciLayer::impl {
log::assert_that(event_view.IsValid(), "assert failed: event_view.IsValid()");
#ifdef TARGET_FLOSS
log::warn("Hardware Error Event with code 0x{:02x}", event_view.GetHardwareCode());
- // Sending SIGTERM to process the exception from BT controller.
+ // Sending signal to indicate BT controller needs to reset.
// The Floss daemon will be restarted. HCI reset during restart will clear the
// error state of the BT controller.
- auto hal = module_.GetDependency<hal::HciHal>();
- hal->markControllerBroken();
- kill(getpid(), SIGTERM);
+ module_.LifeCycleStop();
+ kill(getpid(), SIG_RESET_CTRL);
#else
log::fatal("Hardware Error Event with code 0x{:02x}", event_view.GetHardwareCode());
#endif
@@ -619,6 +629,14 @@ struct HciLayer::hal_callbacks : public hal::HciHalCallbacks {
module_.impl_->incoming_iso_buffer_.Enqueue(std::move(iso), module_.GetHandler());
}
+#ifdef TARGET_FLOSS
+ void controllerNeedsReset() override {
+ log::info("Controller needs reset!");
+ module_.LifeCycleStop();
+ kill(getpid(), SIG_RESET_CTRL);
+ }
+#endif
+
HciLayer& module_;
};
@@ -958,6 +976,7 @@ void HciLayer::StartWithNoHalDependencies(Handler* handler) {
void HciLayer::Stop() {
std::unique_lock<std::recursive_mutex> lock(life_cycle_guard);
+ life_cycle_stopped = true;
auto hal = GetDependency<hal::HciHal>();
hal->unregisterIncomingPacketCallback();
delete hal_callbacks_;
@@ -966,7 +985,11 @@ void HciLayer::Stop() {
impl_->sco_queue_.GetDownEnd()->UnregisterDequeue();
impl_->iso_queue_.GetDownEnd()->UnregisterDequeue();
delete impl_;
+}
+// Function to stop sending and handling incoming packets
+void HciLayer::LifeCycleStop() {
+ std::unique_lock<std::recursive_mutex> lock(life_cycle_guard);
life_cycle_stopped = true;
}
diff --git a/system/gd/hci/hci_layer.h b/system/gd/hci/hci_layer.h
index d30884a625..94f706cf6b 100644
--- a/system/gd/hci/hci_layer.h
+++ b/system/gd/hci/hci_layer.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
@@ -149,6 +149,8 @@ protected:
void Stop() override;
+ void LifeCycleStop();
+
virtual void Disconnect(uint16_t handle, ErrorCode reason);
virtual void ReadRemoteVersion(hci::ErrorCode hci_status, uint16_t handle, uint8_t version,
uint16_t manufacturer_name, uint16_t sub_version);
diff --git a/system/gd/hci/hci_layer_fake.cc b/system/gd/hci/hci_layer_fake.cc
index b09bb5feeb..ffad279ac5 100644
--- a/system/gd/hci/hci_layer_fake.cc
+++ b/system/gd/hci/hci_layer_fake.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/system/gd/hci/hci_layer_fake.h b/system/gd/hci/hci_layer_fake.h
index 4743c0c0ff..d5d024ae77 100644
--- a/system/gd/hci/hci_layer_fake.h
+++ b/system/gd/hci/hci_layer_fake.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/system/gd/hci/hci_layer_mock.h b/system/gd/hci/hci_layer_mock.h
index f207203251..e272071a4b 100644
--- a/system/gd/hci/hci_layer_mock.h
+++ b/system/gd/hci/hci_layer_mock.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2021 The Android Open Source Project
+ * Copyright (C) 2021 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.
diff --git a/system/gd/hci/hci_layer_test.cc b/system/gd/hci/hci_layer_test.cc
index c30094d292..8ac7f846d9 100644
--- a/system/gd/hci/hci_layer_test.cc
+++ b/system/gd/hci/hci_layer_test.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/hci/hci_layer_unittest.cc b/system/gd/hci/hci_layer_unittest.cc
index 86afb1298d..286f9ced19 100644
--- a/system/gd/hci/hci_layer_unittest.cc
+++ b/system/gd/hci/hci_layer_unittest.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/system/gd/hci/hci_metrics_logging.cc b/system/gd/hci/hci_metrics_logging.cc
index 21f66ee3ba..914f2b637a 100644
--- a/system/gd/hci/hci_metrics_logging.cc
+++ b/system/gd/hci/hci_metrics_logging.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2021 The Android Open Source Project
+ * Copyright (C) 2021 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.
diff --git a/system/gd/hci/hci_metrics_logging.h b/system/gd/hci/hci_metrics_logging.h
index 4e1d9b72f4..d9c67ee771 100644
--- a/system/gd/hci/hci_metrics_logging.h
+++ b/system/gd/hci/hci_metrics_logging.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2021 The Android Open Source Project
+ * Copyright (C) 2021 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.
diff --git a/system/gd/hci/hci_packets_fuzz_test.cc b/system/gd/hci/hci_packets_fuzz_test.cc
index 00a053273c..72a0fc9ebf 100644
--- a/system/gd/hci/hci_packets_fuzz_test.cc
+++ b/system/gd/hci/hci_packets_fuzz_test.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/hci/hci_packets_test.cc b/system/gd/hci/hci_packets_test.cc
index 017a5dab98..efb7be096b 100644
--- a/system/gd/hci/hci_packets_test.cc
+++ b/system/gd/hci/hci_packets_test.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/hci/inquiry_interface.h b/system/gd/hci/inquiry_interface.h
index 322e2da30a..74b254a3c1 100644
--- a/system/gd/hci/inquiry_interface.h
+++ b/system/gd/hci/inquiry_interface.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 The Android Open Source Project
+ * Copyright (C) 2024 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.
diff --git a/system/gd/hci/le_acl_connection_interface.h b/system/gd/hci/le_acl_connection_interface.h
index b3081e30b6..67d1729aec 100644
--- a/system/gd/hci/le_acl_connection_interface.h
+++ b/system/gd/hci/le_acl_connection_interface.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/hci/le_address_manager.cc b/system/gd/hci/le_address_manager.cc
index 5073cc1c2c..327ea0f0ca 100644
--- a/system/gd/hci/le_address_manager.cc
+++ b/system/gd/hci/le_address_manager.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
@@ -165,12 +165,8 @@ void LeAddressManager::SetPrivacyPolicyForInitiatorAddress(
min_seconds.count(), max_seconds.count());
enqueue_command_.Run(std::move(packet));
} else {
- if (com::android::bluetooth::flags::non_wake_alarm_for_rpa_rotation()) {
- address_rotation_wake_alarm_ = std::make_unique<os::Alarm>(handler_, true);
- address_rotation_non_wake_alarm_ = std::make_unique<os::Alarm>(handler_, false);
- } else {
- address_rotation_wake_alarm_ = std::make_unique<os::Alarm>(handler_);
- }
+ address_rotation_wake_alarm_ = std::make_unique<os::Alarm>(handler_, true);
+ address_rotation_non_wake_alarm_ = std::make_unique<os::Alarm>(handler_, false);
}
set_random_address();
break;
@@ -229,12 +225,8 @@ void LeAddressManager::SetPrivacyPolicyForInitiatorAddressForTest(
min_seconds.count(), max_seconds.count());
enqueue_command_.Run(std::move(packet));
} else {
- if (com::android::bluetooth::flags::non_wake_alarm_for_rpa_rotation()) {
- address_rotation_wake_alarm_ = std::make_unique<os::Alarm>(handler_, true);
- address_rotation_non_wake_alarm_ = std::make_unique<os::Alarm>(handler_, false);
- } else {
- address_rotation_wake_alarm_ = std::make_unique<os::Alarm>(handler_);
- }
+ address_rotation_wake_alarm_ = std::make_unique<os::Alarm>(handler_, true);
+ address_rotation_non_wake_alarm_ = std::make_unique<os::Alarm>(handler_, false);
set_random_address();
}
break;
@@ -422,31 +414,25 @@ void LeAddressManager::prepare_to_rotate() {
}
void LeAddressManager::schedule_rotate_random_address() {
- if (com::android::bluetooth::flags::non_wake_alarm_for_rpa_rotation()) {
- std::string client_name = "LeAddressManager";
- auto privateAddressIntervalRange = GetNextPrivateAddressIntervalRange(client_name);
- address_rotation_wake_alarm_->Schedule(
- common::BindOnce(
- []() { log::info("deadline wakeup in schedule_rotate_random_address"); }),
- privateAddressIntervalRange.max);
- address_rotation_non_wake_alarm_->Schedule(
- common::BindOnce(&LeAddressManager::prepare_to_rotate, common::Unretained(this)),
- privateAddressIntervalRange.min);
-
- auto now = std::chrono::system_clock::now();
- if (address_rotation_interval_min.has_value()) {
- CheckAddressRotationHappenedInExpectedTimeInterval(
- *address_rotation_interval_min, *address_rotation_interval_max, now, client_name);
- }
-
- // Update the expected range here.
- address_rotation_interval_min.emplace(now + privateAddressIntervalRange.min);
- address_rotation_interval_max.emplace(now + privateAddressIntervalRange.max);
- } else {
- address_rotation_wake_alarm_->Schedule(
- common::BindOnce(&LeAddressManager::prepare_to_rotate, common::Unretained(this)),
- GetNextPrivateAddressIntervalMs());
+ std::string client_name = "LeAddressManager";
+ auto privateAddressIntervalRange = GetNextPrivateAddressIntervalRange(client_name);
+ address_rotation_wake_alarm_->Schedule(
+ common::BindOnce(
+ []() { log::info("deadline wakeup in schedule_rotate_random_address"); }),
+ privateAddressIntervalRange.max);
+ address_rotation_non_wake_alarm_->Schedule(
+ common::BindOnce(&LeAddressManager::prepare_to_rotate, common::Unretained(this)),
+ privateAddressIntervalRange.min);
+
+ auto now = std::chrono::system_clock::now();
+ if (address_rotation_interval_min.has_value()) {
+ CheckAddressRotationHappenedInExpectedTimeInterval(
+ *address_rotation_interval_min, *address_rotation_interval_max, now, client_name);
}
+
+ // Update the expected range here.
+ address_rotation_interval_min.emplace(now + privateAddressIntervalRange.min);
+ address_rotation_interval_max.emplace(now + privateAddressIntervalRange.max);
}
void LeAddressManager::set_random_address() {
diff --git a/system/gd/hci/le_address_manager.h b/system/gd/hci/le_address_manager.h
index a657d8e55c..b985438d4e 100644
--- a/system/gd/hci/le_address_manager.h
+++ b/system/gd/hci/le_address_manager.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/hci/le_address_manager_test.cc b/system/gd/hci/le_address_manager_test.cc
index 33efcb51a2..1d5961be50 100644
--- a/system/gd/hci/le_address_manager_test.cc
+++ b/system/gd/hci/le_address_manager_test.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/hci/le_advertising_interface.h b/system/gd/hci/le_advertising_interface.h
index 5fcddc7123..179a70ff4d 100644
--- a/system/gd/hci/le_advertising_interface.h
+++ b/system/gd/hci/le_advertising_interface.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/hci/le_advertising_manager.cc b/system/gd/hci/le_advertising_manager.cc
index afa8fd300b..d626b2ee15 100644
--- a/system/gd/hci/le_advertising_manager.cc
+++ b/system/gd/hci/le_advertising_manager.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
@@ -374,39 +374,29 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb
log::info("Reenable advertising");
if (was_rotating_address) {
log::info("Scheduling address rotation for advertiser_id={}", advertiser_id);
- if (com::android::bluetooth::flags::non_wake_alarm_for_rpa_rotation()) {
- advertising_sets_[advertiser_id].address_rotation_wake_alarm_ =
- std::make_unique<os::Alarm>(module_handler_, true);
- advertising_sets_[advertiser_id].address_rotation_non_wake_alarm_ =
- std::make_unique<os::Alarm>(module_handler_, false);
-
- std::string client_name = "advertising_set_" + std::to_string(advertiser_id);
- auto privateAddressIntervalRange =
- le_address_manager_->GetNextPrivateAddressIntervalRange(client_name);
-
- advertising_sets_[advertiser_id].address_rotation_wake_alarm_->Schedule(
- common::BindOnce(
- []() { log::info("deadline wakeup in handle_set_terminated"); }),
- privateAddressIntervalRange.max);
- advertising_sets_[advertiser_id].address_rotation_non_wake_alarm_->Schedule(
- common::BindOnce(&impl::set_advertising_set_random_address_on_timer,
- common::Unretained(this), advertiser_id),
- privateAddressIntervalRange.min);
-
- // Update the expected range here.
- auto now = std::chrono::system_clock::now();
- advertising_sets_[advertiser_id].address_rotation_interval_min.emplace(
- now + privateAddressIntervalRange.min);
- advertising_sets_[advertiser_id].address_rotation_interval_max.emplace(
- now + privateAddressIntervalRange.max);
- } else {
- advertising_sets_[advertiser_id].address_rotation_wake_alarm_ =
- std::make_unique<os::Alarm>(module_handler_);
- advertising_sets_[advertiser_id].address_rotation_wake_alarm_->Schedule(
- common::BindOnce(&impl::set_advertising_set_random_address_on_timer,
- common::Unretained(this), advertiser_id),
- le_address_manager_->GetNextPrivateAddressIntervalMs());
- }
+ advertising_sets_[advertiser_id].address_rotation_wake_alarm_ =
+ std::make_unique<os::Alarm>(module_handler_, true);
+ advertising_sets_[advertiser_id].address_rotation_non_wake_alarm_ =
+ std::make_unique<os::Alarm>(module_handler_, false);
+
+ std::string client_name = "advertising_set_" + std::to_string(advertiser_id);
+ auto privateAddressIntervalRange =
+ le_address_manager_->GetNextPrivateAddressIntervalRange(client_name);
+
+ advertising_sets_[advertiser_id].address_rotation_wake_alarm_->Schedule(
+ common::BindOnce([]() { log::info("deadline wakeup in handle_set_terminated"); }),
+ privateAddressIntervalRange.max);
+ advertising_sets_[advertiser_id].address_rotation_non_wake_alarm_->Schedule(
+ common::BindOnce(&impl::set_advertising_set_random_address_on_timer,
+ common::Unretained(this), advertiser_id),
+ privateAddressIntervalRange.min);
+
+ // Update the expected range here.
+ auto now = std::chrono::system_clock::now();
+ advertising_sets_[advertiser_id].address_rotation_interval_min.emplace(
+ now + privateAddressIntervalRange.min);
+ advertising_sets_[advertiser_id].address_rotation_interval_max.emplace(
+ now + privateAddressIntervalRange.max);
}
enable_advertiser(advertiser_id, true, 0, 0);
}
@@ -673,40 +663,31 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb
!leaudio_requested_nrpa && (!controller_->IsRpaGenerationSupported())) {
// start timer for random address
log::info("Scheduling address rotation for advertiser_id={}", id);
- if (com::android::bluetooth::flags::non_wake_alarm_for_rpa_rotation()) {
- advertising_sets_[id].address_rotation_wake_alarm_ =
- std::make_unique<os::Alarm>(module_handler_, true);
- advertising_sets_[id].address_rotation_non_wake_alarm_ =
- std::make_unique<os::Alarm>(module_handler_, false);
-
- std::string client_name = "advertising_set_" + std::to_string(id);
- auto privateAddressIntervalRange =
- le_address_manager_->GetNextPrivateAddressIntervalRange(client_name);
-
- advertising_sets_[id].address_rotation_wake_alarm_->Schedule(
- common::BindOnce([]() {
- log::info("deadline wakeup in create_extended_advertiser_with_id");
- }),
- privateAddressIntervalRange.max);
- advertising_sets_[id].address_rotation_non_wake_alarm_->Schedule(
- common::BindOnce(&impl::set_advertising_set_random_address_on_timer,
- common::Unretained(this), id),
- privateAddressIntervalRange.min);
-
- // Update the expected range here.
- auto now = std::chrono::system_clock::now();
- advertising_sets_[id].address_rotation_interval_min.emplace(
- now + privateAddressIntervalRange.min);
- advertising_sets_[id].address_rotation_interval_max.emplace(
- now + privateAddressIntervalRange.max);
- } else {
- advertising_sets_[id].address_rotation_wake_alarm_ =
- std::make_unique<os::Alarm>(module_handler_);
- advertising_sets_[id].address_rotation_wake_alarm_->Schedule(
- common::BindOnce(&impl::set_advertising_set_random_address_on_timer,
- common::Unretained(this), id),
- le_address_manager_->GetNextPrivateAddressIntervalMs());
- }
+ advertising_sets_[id].address_rotation_wake_alarm_ =
+ std::make_unique<os::Alarm>(module_handler_, true);
+ advertising_sets_[id].address_rotation_non_wake_alarm_ =
+ std::make_unique<os::Alarm>(module_handler_, false);
+
+ std::string client_name = "advertising_set_" + std::to_string(id);
+ auto privateAddressIntervalRange =
+ le_address_manager_->GetNextPrivateAddressIntervalRange(client_name);
+
+ advertising_sets_[id].address_rotation_wake_alarm_->Schedule(
+ common::BindOnce([]() {
+ log::info("deadline wakeup in create_extended_advertiser_with_id");
+ }),
+ privateAddressIntervalRange.max);
+ advertising_sets_[id].address_rotation_non_wake_alarm_->Schedule(
+ common::BindOnce(&impl::set_advertising_set_random_address_on_timer,
+ common::Unretained(this), id),
+ privateAddressIntervalRange.min);
+
+ // Update the expected range here.
+ auto now = std::chrono::system_clock::now();
+ advertising_sets_[id].address_rotation_interval_min.emplace(
+ now + privateAddressIntervalRange.min);
+ advertising_sets_[id].address_rotation_interval_max.emplace(
+ now + privateAddressIntervalRange.max);
}
}
if (config.advertising_type == AdvertisingType::ADV_IND ||
@@ -859,39 +840,31 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb
}
log::info("Scheduling address rotation for advertiser_id={}", advertiser_id);
- if (com::android::bluetooth::flags::non_wake_alarm_for_rpa_rotation()) {
- std::string client_name = "advertising_set_" + std::to_string(advertiser_id);
- auto privateAddressIntervalRange =
- le_address_manager_->GetNextPrivateAddressIntervalRange(client_name);
- advertising_sets_[advertiser_id].address_rotation_wake_alarm_->Schedule(
- common::BindOnce([]() {
- log::info("deadline wakeup in set_advertising_set_random_address_on_timer");
- }),
- privateAddressIntervalRange.max);
- advertising_sets_[advertiser_id].address_rotation_non_wake_alarm_->Schedule(
- common::BindOnce(&impl::set_advertising_set_random_address_on_timer,
- common::Unretained(this), advertiser_id),
- privateAddressIntervalRange.min);
-
- auto now = std::chrono::system_clock::now();
- if (advertising_sets_[advertiser_id].address_rotation_interval_min.has_value()) {
- le_address_manager_->CheckAddressRotationHappenedInExpectedTimeInterval(
- *(advertising_sets_[advertiser_id].address_rotation_interval_min),
- *(advertising_sets_[advertiser_id].address_rotation_interval_max), now,
- client_name);
- }
-
- // Update the expected range here.
- advertising_sets_[advertiser_id].address_rotation_interval_min.emplace(
- now + privateAddressIntervalRange.min);
- advertising_sets_[advertiser_id].address_rotation_interval_max.emplace(
- now + privateAddressIntervalRange.max);
- } else {
- advertising_sets_[advertiser_id].address_rotation_wake_alarm_->Schedule(
- common::BindOnce(&impl::set_advertising_set_random_address_on_timer,
- common::Unretained(this), advertiser_id),
- le_address_manager_->GetNextPrivateAddressIntervalMs());
+ std::string client_name = "advertising_set_" + std::to_string(advertiser_id);
+ auto privateAddressIntervalRange =
+ le_address_manager_->GetNextPrivateAddressIntervalRange(client_name);
+ advertising_sets_[advertiser_id].address_rotation_wake_alarm_->Schedule(
+ common::BindOnce([]() {
+ log::info("deadline wakeup in set_advertising_set_random_address_on_timer");
+ }),
+ privateAddressIntervalRange.max);
+ advertising_sets_[advertiser_id].address_rotation_non_wake_alarm_->Schedule(
+ common::BindOnce(&impl::set_advertising_set_random_address_on_timer,
+ common::Unretained(this), advertiser_id),
+ privateAddressIntervalRange.min);
+
+ auto now = std::chrono::system_clock::now();
+ if (advertising_sets_[advertiser_id].address_rotation_interval_min.has_value()) {
+ le_address_manager_->CheckAddressRotationHappenedInExpectedTimeInterval(
+ *(advertising_sets_[advertiser_id].address_rotation_interval_min),
+ *(advertising_sets_[advertiser_id].address_rotation_interval_max), now, client_name);
}
+
+ // Update the expected range here.
+ advertising_sets_[advertiser_id].address_rotation_interval_min.emplace(
+ now + privateAddressIntervalRange.min);
+ advertising_sets_[advertiser_id].address_rotation_interval_max.emplace(
+ now + privateAddressIntervalRange.max);
}
void register_advertiser(
diff --git a/system/gd/hci/le_advertising_manager.h b/system/gd/hci/le_advertising_manager.h
index fe614861e2..b50dd2623c 100644
--- a/system/gd/hci/le_advertising_manager.h
+++ b/system/gd/hci/le_advertising_manager.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/hci/le_advertising_manager_mock.h b/system/gd/hci/le_advertising_manager_mock.h
index baf2e263f1..e54e2ae584 100644
--- a/system/gd/hci/le_advertising_manager_mock.h
+++ b/system/gd/hci/le_advertising_manager_mock.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/hci/le_advertising_manager_test.cc b/system/gd/hci/le_advertising_manager_test.cc
index 12fa70d263..efe9462137 100644
--- a/system/gd/hci/le_advertising_manager_test.cc
+++ b/system/gd/hci/le_advertising_manager_test.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/hci/le_iso_interface.h b/system/gd/hci/le_iso_interface.h
index 33aa1c4461..ec05320438 100644
--- a/system/gd/hci/le_iso_interface.h
+++ b/system/gd/hci/le_iso_interface.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/hci/le_periodic_sync_manager.h b/system/gd/hci/le_periodic_sync_manager.h
index 09c557549a..d600371480 100644
--- a/system/gd/hci/le_periodic_sync_manager.h
+++ b/system/gd/hci/le_periodic_sync_manager.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/system/gd/hci/le_periodic_sync_manager_test.cc b/system/gd/hci/le_periodic_sync_manager_test.cc
index 18a76ae18c..cba8905dfd 100644
--- a/system/gd/hci/le_periodic_sync_manager_test.cc
+++ b/system/gd/hci/le_periodic_sync_manager_test.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/system/gd/hci/le_rand_callback.h b/system/gd/hci/le_rand_callback.h
index 54db17e4f9..617a7c45a9 100644
--- a/system/gd/hci/le_rand_callback.h
+++ b/system/gd/hci/le_rand_callback.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/system/gd/hci/le_scanning_callback.h b/system/gd/hci/le_scanning_callback.h
index 4bd75dbbc4..6f086a3673 100644
--- a/system/gd/hci/le_scanning_callback.h
+++ b/system/gd/hci/le_scanning_callback.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/system/gd/hci/le_scanning_interface.h b/system/gd/hci/le_scanning_interface.h
index d26cf53604..6f0c456c3e 100644
--- a/system/gd/hci/le_scanning_interface.h
+++ b/system/gd/hci/le_scanning_interface.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/hci/le_scanning_manager.cc b/system/gd/hci/le_scanning_manager.cc
index e80caaf23c..439b6241c1 100644
--- a/system/gd/hci/le_scanning_manager.cc
+++ b/system/gd/hci/le_scanning_manager.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/hci/le_scanning_manager.h b/system/gd/hci/le_scanning_manager.h
index 90043145a9..e09bf304af 100644
--- a/system/gd/hci/le_scanning_manager.h
+++ b/system/gd/hci/le_scanning_manager.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/hci/le_scanning_manager_mock.h b/system/gd/hci/le_scanning_manager_mock.h
index f62012c38c..b72ce45fd2 100644
--- a/system/gd/hci/le_scanning_manager_mock.h
+++ b/system/gd/hci/le_scanning_manager_mock.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/hci/le_scanning_manager_test.cc b/system/gd/hci/le_scanning_manager_test.cc
index 134702cb4a..f19ac15862 100644
--- a/system/gd/hci/le_scanning_manager_test.cc
+++ b/system/gd/hci/le_scanning_manager_test.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/hci/le_scanning_reassembler.cc b/system/gd/hci/le_scanning_reassembler.cc
index 8f8ad06b00..80e7be28d2 100644
--- a/system/gd/hci/le_scanning_reassembler.cc
+++ b/system/gd/hci/le_scanning_reassembler.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 The Android Open Source Project
+ * Copyright (C) 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.
diff --git a/system/gd/hci/le_scanning_reassembler.h b/system/gd/hci/le_scanning_reassembler.h
index afc4b9b303..327d0445f7 100644
--- a/system/gd/hci/le_scanning_reassembler.h
+++ b/system/gd/hci/le_scanning_reassembler.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/hci/le_scanning_reassembler_test.cc b/system/gd/hci/le_scanning_reassembler_test.cc
index d2461391f9..beaa0a375b 100644
--- a/system/gd/hci/le_scanning_reassembler_test.cc
+++ b/system/gd/hci/le_scanning_reassembler_test.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 The Android Open Source Project
+ * Copyright (C) 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.
diff --git a/system/gd/hci/le_security_interface.h b/system/gd/hci/le_security_interface.h
index 93a2122d8f..7bdfb590e9 100644
--- a/system/gd/hci/le_security_interface.h
+++ b/system/gd/hci/le_security_interface.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/hci/link_key.cc b/system/gd/hci/link_key.cc
index 78ea1a48ea..6795b904af 100644
--- a/system/gd/hci/link_key.cc
+++ b/system/gd/hci/link_key.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/hci/link_key.h b/system/gd/hci/link_key.h
index fc55c0cacc..9f1930c1f9 100644
--- a/system/gd/hci/link_key.h
+++ b/system/gd/hci/link_key.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/hci/msft.cc b/system/gd/hci/msft.cc
index 1c5a700030..c542bb950f 100644
--- a/system/gd/hci/msft.cc
+++ b/system/gd/hci/msft.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/system/gd/hci/msft.h b/system/gd/hci/msft.h
index 70b41ee8ce..6e9357d834 100644
--- a/system/gd/hci/msft.h
+++ b/system/gd/hci/msft.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/system/gd/hci/octets.h b/system/gd/hci/octets.h
index 0eba1561c0..159dc9df09 100644
--- a/system/gd/hci/octets.h
+++ b/system/gd/hci/octets.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 The Android Open Source Project
+ * Copyright (C) 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.
diff --git a/system/gd/hci/remote_name_request.cc b/system/gd/hci/remote_name_request.cc
index 2f703feca9..e2f5433f27 100644
--- a/system/gd/hci/remote_name_request.cc
+++ b/system/gd/hci/remote_name_request.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/system/gd/hci/remote_name_request.h b/system/gd/hci/remote_name_request.h
index c8553c7c2f..ce6f2a8337 100644
--- a/system/gd/hci/remote_name_request.h
+++ b/system/gd/hci/remote_name_request.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/system/gd/hci/remote_name_request_test.cc b/system/gd/hci/remote_name_request_test.cc
index 43367e89be..948d82bc89 100644
--- a/system/gd/hci/remote_name_request_test.cc
+++ b/system/gd/hci/remote_name_request_test.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/system/gd/hci/security_interface.h b/system/gd/hci/security_interface.h
index ad7a628b73..606e2edf01 100644
--- a/system/gd/hci/security_interface.h
+++ b/system/gd/hci/security_interface.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/hci/uuid_unittest.cc b/system/gd/hci/uuid_unittest.cc
index 3656a13ffd..c148c6b39d 100644
--- a/system/gd/hci/uuid_unittest.cc
+++ b/system/gd/hci/uuid_unittest.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/lpp/lpp_offload_interface.h b/system/gd/lpp/lpp_offload_interface.h
index 388466f2e5..1387423fdb 100644
--- a/system/gd/lpp/lpp_offload_interface.h
+++ b/system/gd/lpp/lpp_offload_interface.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 The Android Open Source Project
+ * Copyright (C) 2024 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.
diff --git a/system/gd/lpp/lpp_offload_interface_mock.h b/system/gd/lpp/lpp_offload_interface_mock.h
index 03cd5f4f52..6ac1490830 100644
--- a/system/gd/lpp/lpp_offload_interface_mock.h
+++ b/system/gd/lpp/lpp_offload_interface_mock.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 The Android Open Source Project
+ * Copyright (C) 2024 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.
diff --git a/system/gd/lpp/lpp_offload_manager.cc b/system/gd/lpp/lpp_offload_manager.cc
index c5c1fb247e..4518cc96fe 100644
--- a/system/gd/lpp/lpp_offload_manager.cc
+++ b/system/gd/lpp/lpp_offload_manager.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 The Android Open Source Project
+ * Copyright (C) 2024 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.
diff --git a/system/gd/lpp/lpp_offload_manager.h b/system/gd/lpp/lpp_offload_manager.h
index 90097f77bd..c8b90a69df 100644
--- a/system/gd/lpp/lpp_offload_manager.h
+++ b/system/gd/lpp/lpp_offload_manager.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 The Android Open Source Project
+ * Copyright (C) 2024 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.
diff --git a/system/gd/metrics/bluetooth_event.cc b/system/gd/metrics/bluetooth_event.cc
index 4311aeb2e1..6fa3678bec 100644
--- a/system/gd/metrics/bluetooth_event.cc
+++ b/system/gd/metrics/bluetooth_event.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 The Android Open Source Project
+ * Copyright (C) 2024 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.
diff --git a/system/gd/metrics/bluetooth_event.h b/system/gd/metrics/bluetooth_event.h
index 50c3f88d75..65875bcaa7 100644
--- a/system/gd/metrics/bluetooth_event.h
+++ b/system/gd/metrics/bluetooth_event.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 The Android Open Source Project
+ * Copyright (C) 2024 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.
diff --git a/system/gd/metrics/chromeos/metrics.cc b/system/gd/metrics/chromeos/metrics.cc
index 87966a379c..ee84dd7095 100644
--- a/system/gd/metrics/chromeos/metrics.cc
+++ b/system/gd/metrics/chromeos/metrics.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/system/gd/metrics/chromeos/metrics_allowlist.cc b/system/gd/metrics/chromeos/metrics_allowlist.cc
index 33f2bf6dde..67c2e2647b 100644
--- a/system/gd/metrics/chromeos/metrics_allowlist.cc
+++ b/system/gd/metrics/chromeos/metrics_allowlist.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/system/gd/metrics/chromeos/metrics_allowlist.h b/system/gd/metrics/chromeos/metrics_allowlist.h
index 6bd1530558..799c81b87f 100644
--- a/system/gd/metrics/chromeos/metrics_allowlist.h
+++ b/system/gd/metrics/chromeos/metrics_allowlist.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/system/gd/metrics/chromeos/metrics_event.cc b/system/gd/metrics/chromeos/metrics_event.cc
index 80f517da56..d7e0d76bb3 100644
--- a/system/gd/metrics/chromeos/metrics_event.cc
+++ b/system/gd/metrics/chromeos/metrics_event.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/system/gd/metrics/chromeos/metrics_event.h b/system/gd/metrics/chromeos/metrics_event.h
index b4ddb403ba..1b685cf358 100644
--- a/system/gd/metrics/chromeos/metrics_event.h
+++ b/system/gd/metrics/chromeos/metrics_event.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/system/gd/metrics/counter_metrics.cc b/system/gd/metrics/counter_metrics.cc
index 99ba652bf9..5bafd90599 100644
--- a/system/gd/metrics/counter_metrics.cc
+++ b/system/gd/metrics/counter_metrics.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2021 The Android Open Source Project
+ * Copyright (C) 2021 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.
diff --git a/system/gd/metrics/counter_metrics.h b/system/gd/metrics/counter_metrics.h
index e5a63f6394..88c7711f92 100644
--- a/system/gd/metrics/counter_metrics.h
+++ b/system/gd/metrics/counter_metrics.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2021 The Android Open Source Project
+ * Copyright (C) 2021 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.
diff --git a/system/gd/metrics/counter_metrics_unittest.cc b/system/gd/metrics/counter_metrics_unittest.cc
index cbaf7f0072..eb5545ca19 100644
--- a/system/gd/metrics/counter_metrics_unittest.cc
+++ b/system/gd/metrics/counter_metrics_unittest.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2021 The Android Open Source Project
+ * Copyright (C) 2021 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.
diff --git a/system/gd/metrics/linux/metrics.cc b/system/gd/metrics/linux/metrics.cc
index 9be10aeec9..f15ebb4695 100644
--- a/system/gd/metrics/linux/metrics.cc
+++ b/system/gd/metrics/linux/metrics.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/system/gd/metrics/metrics.h b/system/gd/metrics/metrics.h
index e26ded4e17..36fe66ed06 100644
--- a/system/gd/metrics/metrics.h
+++ b/system/gd/metrics/metrics.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/system/gd/metrics/utils.cc b/system/gd/metrics/utils.cc
index b059bb7133..b39b27f5b7 100644
--- a/system/gd/metrics/utils.cc
+++ b/system/gd/metrics/utils.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/system/gd/metrics/utils.h b/system/gd/metrics/utils.h
index 316ffdc74e..05d8d6044b 100644
--- a/system/gd/metrics/utils.h
+++ b/system/gd/metrics/utils.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/system/gd/module.cc b/system/gd/module.cc
index d5ea4c4fd3..76b386bbfe 100644
--- a/system/gd/module.cc
+++ b/system/gd/module.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
@@ -128,10 +128,18 @@ void ModuleRegistry::StopAll() {
auto module = Get(*it);
last_instance_ = "stopping " + module->ToString();
- // Clear the handler before stopping the module to allow it to shut down gracefully.
- log::info("Stopping Handler of Module {}", module->ToString());
- module->handler_->Clear();
- module->handler_->WaitUntilStopped(kModuleStopTimeout);
+ /*
+ * b/393449774 since we have now shifted to a single handler for all modules, we don't need
+ * to clear the handler here, it will be done in the respective teardown.
+ * Since we have a single handler, we need to make sure that the handler instance is deleted
+ * only once, otherwise we will see a crash as a handler can only be cleared once.
+ */
+ if (!com::android::bluetooth::flags::same_handler_for_all_modules()) {
+ // Clear the handler before stopping the module to allow it to shut down gracefully.
+ log::info("Stopping Handler of Module {}", module->ToString());
+ module->handler_->Clear();
+ module->handler_->WaitUntilStopped(kModuleStopTimeout);
+ }
log::info("Stopping Module {}", module->ToString());
module->Stop();
}
@@ -144,7 +152,9 @@ void ModuleRegistry::StopAll() {
auto instance = started_modules_.find(*it);
log::assert_that(instance != started_modules_.end(),
"assert failed: instance != started_modules_.end()");
- delete instance->second->handler_;
+ if (!com::android::bluetooth::flags::same_handler_for_all_modules()) {
+ delete instance->second->handler_;
+ }
delete instance->second;
started_modules_.erase(instance);
}
@@ -165,4 +175,15 @@ os::Handler* ModuleRegistry::GetModuleHandler(const ModuleFactory* module) const
return nullptr;
}
+// Override the StopAll method to use the test thread and handler.
+// This function will take care of releasing the handler instances.
+void TestModuleRegistry::StopAll() {
+ os::Handler* handler = GetTestHandler();
+ handler->Clear();
+ if (com::android::bluetooth::flags::same_handler_for_all_modules()) {
+ handler->WaitUntilStopped(kHandlerStopTimeout);
+ }
+ ModuleRegistry::StopAll(); // call the base class StopAll
+ delete handler;
+}
} // namespace bluetooth
diff --git a/system/gd/module.h b/system/gd/module.h
index b53f992ccf..57e4db7d16 100644
--- a/system/gd/module.h
+++ b/system/gd/module.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
@@ -32,6 +32,9 @@
#include "os/thread.h"
namespace bluetooth {
+// Timeout for waiting for a handler to stop, used in Handler::WaitUntilStopped()
+constexpr std::chrono::milliseconds kHandlerStopTimeout = std::chrono::milliseconds(2000);
+
namespace shim {
class Stack;
} // namespace shim
@@ -191,6 +194,9 @@ public:
os::Thread& GetTestThread() { return test_thread; }
os::Handler* GetTestHandler() { return test_handler_; }
+ // Override the StopAll method to use the test thread and handler.
+ void StopAll();
+
bool SynchronizeModuleHandler(const ModuleFactory* module,
std::chrono::milliseconds timeout) const {
return SynchronizeHandler(GetTestModuleHandler(module), timeout);
diff --git a/system/gd/module_unittest.cc b/system/gd/module_unittest.cc
index d89be74219..8fb140c229 100644
--- a/system/gd/module_unittest.cc
+++ b/system/gd/module_unittest.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
@@ -22,6 +22,7 @@
#include <sstream>
#include <string>
+#include "com_android_bluetooth_flags.h"
#include "gtest/gtest.h"
#include "os/handler.h"
#include "os/thread.h"
@@ -41,9 +42,12 @@ protected:
void TearDown() override {
handler_->Clear();
+ if (com::android::bluetooth::flags::same_handler_for_all_modules()) {
+ handler_->WaitUntilStopped(kHandlerStopTimeout);
+ }
delete registry_;
- delete thread_;
delete handler_;
+ delete thread_;
}
ModuleRegistry* registry_;
diff --git a/system/gd/os/alarm.h b/system/gd/os/alarm.h
index 2eeea77b1f..5f5f21c9c8 100644
--- a/system/gd/os/alarm.h
+++ b/system/gd/os/alarm.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/os/alarm_benchmark.cc b/system/gd/os/alarm_benchmark.cc
index cfe3c3db80..3839a1695d 100644
--- a/system/gd/os/alarm_benchmark.cc
+++ b/system/gd/os/alarm_benchmark.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/os/android/metrics.cc b/system/gd/os/android/metrics.cc
index 3b6d9602b0..78b12c8d96 100644
--- a/system/gd/os/android/metrics.cc
+++ b/system/gd/os/android/metrics.cc
@@ -66,6 +66,9 @@ struct formatter<android::bluetooth::rfcomm::SocketConnectionSecurity>
: enum_formatter<android::bluetooth::rfcomm::SocketConnectionSecurity> {};
template <>
struct formatter<android::bluetooth::BtaStatus> : enum_formatter<android::bluetooth::BtaStatus> {};
+template <>
+struct formatter<android::bluetooth::SocketErrorEnum>
+ : enum_formatter<android::bluetooth::SocketErrorEnum> {};
} // namespace std
namespace bluetooth {
@@ -332,22 +335,28 @@ void LogMetricSdpAttribute(const Address& address, uint16_t protocol_uuid, uint1
void LogMetricSocketConnectionState(const Address& address, int port, int type,
android::bluetooth::SocketConnectionstateEnum connection_state,
int64_t tx_bytes, int64_t rx_bytes, int uid, int server_port,
- android::bluetooth::SocketRoleEnum socket_role) {
+ android::bluetooth::SocketRoleEnum socket_role,
+ uint64_t connection_duration_ms,
+ android::bluetooth::SocketErrorEnum error_code,
+ bool is_hardware_offload) {
int metric_id = 0;
if (!address.IsEmpty()) {
metric_id = MetricIdManager::GetInstance().AllocateId(address);
}
+
int ret = stats_write(BLUETOOTH_SOCKET_CONNECTION_STATE_CHANGED, byteField, port, type,
connection_state, tx_bytes, rx_bytes, uid, server_port, socket_role,
- metric_id, 0 /* connection_duration_ms */, 1 /* error_code */,
- 0 /* is_hardware_offload */);
+ metric_id, static_cast<int64_t>(connection_duration_ms), error_code,
+ is_hardware_offload);
+
if (ret < 0) {
log::warn(
"Failed for {}, port {}, type {}, state {}, tx_bytes {}, rx_bytes {}, uid {}, "
"server_port "
- "{}, socket_role {}, error {}",
+ "{}, socket_role {}, error {}, connection_duration_ms {}, socket_error_code {}, "
+ "is_hardware_offload {}",
address, port, type, connection_state, tx_bytes, rx_bytes, uid, server_port,
- socket_role, ret);
+ socket_role, ret, connection_duration_ms, error_code, is_hardware_offload);
}
}
diff --git a/system/gd/os/android/parameter_provider.cc b/system/gd/os/android/parameter_provider.cc
index c8507ddf32..06132e677f 100644
--- a/system/gd/os/android/parameter_provider.cc
+++ b/system/gd/os/android/parameter_provider.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/os/android/system_properties.cc b/system/gd/os/android/system_properties.cc
index d0f2707173..7b246128b5 100644
--- a/system/gd/os/android/system_properties.cc
+++ b/system/gd/os/android/system_properties.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/os/bt_keystore.h b/system/gd/os/bt_keystore.h
index 68005acdea..daff5f8217 100644
--- a/system/gd/os/bt_keystore.h
+++ b/system/gd/os/bt_keystore.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/os/chromeos/metrics.cc b/system/gd/os/chromeos/metrics.cc
index 70258d335a..b7921fe308 100644
--- a/system/gd/os/chromeos/metrics.cc
+++ b/system/gd/os/chromeos/metrics.cc
@@ -35,7 +35,10 @@ void LogMetricClassicPairingEvent(const Address& address, uint16_t handle, uint3
void LogMetricSocketConnectionState(const Address& address, int port, int type,
android::bluetooth::SocketConnectionstateEnum connection_state,
int64_t tx_bytes, int64_t rx_bytes, int uid, int server_port,
- android::bluetooth::SocketRoleEnum socket_role) {}
+ android::bluetooth::SocketRoleEnum socket_role,
+ uint64_t /* connection_duration_ms */,
+ android::bluetooth::SocketErrorEnum /* error_code */,
+ bool /* is_hardware_offload */) {}
void LogMetricHciTimeoutEvent(uint32_t hci_cmd) {}
diff --git a/system/gd/os/chromeos/parameter_provider.cc b/system/gd/os/chromeos/parameter_provider.cc
index a8ee19c5a6..0cfd60b82a 100644
--- a/system/gd/os/chromeos/parameter_provider.cc
+++ b/system/gd/os/chromeos/parameter_provider.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/os/chromeos/system_properties.cc b/system/gd/os/chromeos/system_properties.cc
index 16e474c8d2..07645d3390 100644
--- a/system/gd/os/chromeos/system_properties.cc
+++ b/system/gd/os/chromeos/system_properties.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/os/fake_timer/fake_timerfd.cc b/system/gd/os/fake_timer/fake_timerfd.cc
index 400a92743c..cacd37bd7f 100644
--- a/system/gd/os/fake_timer/fake_timerfd.cc
+++ b/system/gd/os/fake_timer/fake_timerfd.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/os/fake_timer/fake_timerfd.h b/system/gd/os/fake_timer/fake_timerfd.h
index 31a698aec9..2183edb57c 100644
--- a/system/gd/os/fake_timer/fake_timerfd.h
+++ b/system/gd/os/fake_timer/fake_timerfd.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/os/files.h b/system/gd/os/files.h
index 34a9f2f5b9..4efb0afdd4 100644
--- a/system/gd/os/files.h
+++ b/system/gd/os/files.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/os/fuzz/dev_null_queue.h b/system/gd/os/fuzz/dev_null_queue.h
index 46f88d3fc4..3ffd2adcca 100644
--- a/system/gd/os/fuzz/dev_null_queue.h
+++ b/system/gd/os/fuzz/dev_null_queue.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/os/fuzz/fuzz_inject_queue.h b/system/gd/os/fuzz/fuzz_inject_queue.h
index 322faa0d57..5cd60b1f2b 100644
--- a/system/gd/os/fuzz/fuzz_inject_queue.h
+++ b/system/gd/os/fuzz/fuzz_inject_queue.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/os/handler.cc b/system/gd/os/handler.cc
index 388fcd4c72..919bf0be40 100644
--- a/system/gd/os/handler.cc
+++ b/system/gd/os/handler.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/os/handler.h b/system/gd/os/handler.h
index 4bb75b86f4..167f475d68 100644
--- a/system/gd/os/handler.h
+++ b/system/gd/os/handler.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/os/handler_unittest.cc b/system/gd/os/handler_unittest.cc
index 7306effd30..cca5b955cc 100644
--- a/system/gd/os/handler_unittest.cc
+++ b/system/gd/os/handler_unittest.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/os/host/metrics.cc b/system/gd/os/host/metrics.cc
index 61734e6a81..a333113238 100644
--- a/system/gd/os/host/metrics.cc
+++ b/system/gd/os/host/metrics.cc
@@ -32,7 +32,8 @@ void LogMetricSocketConnectionState(
const Address& /* address */, int /* port */, int /* type */,
android::bluetooth::SocketConnectionstateEnum /* connection_state */,
int64_t /* tx_bytes */, int64_t /* rx_bytes */, int /* uid */, int /* server_port */,
- android::bluetooth::SocketRoleEnum /* socket_role */) {}
+ android::bluetooth::SocketRoleEnum /* socket_role */, uint64_t /* connection_duration_ms */,
+ android::bluetooth::SocketErrorEnum /* error_code */, bool /* is_hardware_offload */) {}
void LogMetricHciTimeoutEvent(uint32_t /* hci_cmd */) {}
diff --git a/system/gd/os/host/parameter_provider.cc b/system/gd/os/host/parameter_provider.cc
index 7b150da4be..e56f82731f 100644
--- a/system/gd/os/host/parameter_provider.cc
+++ b/system/gd/os/host/parameter_provider.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/os/host/system_properties.cc b/system/gd/os/host/system_properties.cc
index 5b28659612..2d49810adb 100644
--- a/system/gd/os/host/system_properties.cc
+++ b/system/gd/os/host/system_properties.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/os/linux/metrics.cc b/system/gd/os/linux/metrics.cc
index 45fca1f4ee..7b727f38f2 100644
--- a/system/gd/os/linux/metrics.cc
+++ b/system/gd/os/linux/metrics.cc
@@ -30,7 +30,10 @@ void LogMetricClassicPairingEvent(const Address& address, uint16_t handle, uint3
void LogMetricSocketConnectionState(const Address& address, int port, int type,
android::bluetooth::SocketConnectionstateEnum connection_state,
int64_t tx_bytes, int64_t rx_bytes, int uid, int server_port,
- android::bluetooth::SocketRoleEnum socket_role) {}
+ android::bluetooth::SocketRoleEnum socket_role,
+ uint64_t /* connection_duration_ms */,
+ android::bluetooth::SocketErrorEnum /* error_code */,
+ bool /* is_hardware_offload */) {}
void LogMetricHciTimeoutEvent(uint32_t hci_cmd) {}
diff --git a/system/gd/os/linux/parameter_provider.cc b/system/gd/os/linux/parameter_provider.cc
index a8ee19c5a6..0cfd60b82a 100644
--- a/system/gd/os/linux/parameter_provider.cc
+++ b/system/gd/os/linux/parameter_provider.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/os/linux/system_properties.cc b/system/gd/os/linux/system_properties.cc
index 16e474c8d2..07645d3390 100644
--- a/system/gd/os/linux/system_properties.cc
+++ b/system/gd/os/linux/system_properties.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/os/linux_generic/alarm.cc b/system/gd/os/linux_generic/alarm.cc
index 9f85016f0b..a378ca93cd 100644
--- a/system/gd/os/linux_generic/alarm.cc
+++ b/system/gd/os/linux_generic/alarm.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
@@ -17,7 +17,6 @@
#include "os/alarm.h"
#include <bluetooth/log.h>
-#include <com_android_bluetooth_flags.h>
#include <sys/timerfd.h>
#include <unistd.h>
@@ -41,8 +40,7 @@ using common::OnceClosure;
Alarm::Alarm(Handler* handler) : Alarm(handler, true) {}
Alarm::Alarm(Handler* handler, bool isWakeAlarm) : handler_(handler) {
- int timerfd_flag =
- com::android::bluetooth::flags::non_wake_alarm_for_rpa_rotation() ? TFD_NONBLOCK : 0;
+ int timerfd_flag = TFD_NONBLOCK;
fd_ = TIMERFD_CREATE(isWakeAlarm ? ALARM_CLOCK : CLOCK_BOOTTIME, timerfd_flag);
@@ -85,7 +83,7 @@ void Alarm::on_fire() {
auto bytes_read = read(fd_, &times_invoked, sizeof(uint64_t));
lock.unlock();
- if (com::android::bluetooth::flags::non_wake_alarm_for_rpa_rotation() && bytes_read == -1) {
+ if (bytes_read == -1) {
log::debug("No data to read.");
if (errno == EAGAIN || errno == EWOULDBLOCK) {
log::debug("Alarm is already canceled or rescheduled.");
diff --git a/system/gd/os/linux_generic/alarm_timerfd_unittest.cc b/system/gd/os/linux_generic/alarm_timerfd_unittest.cc
index bcf802b86d..5d0698ce31 100644
--- a/system/gd/os/linux_generic/alarm_timerfd_unittest.cc
+++ b/system/gd/os/linux_generic/alarm_timerfd_unittest.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 The Android Open Source Project
+ * Copyright (C) 2024 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.
diff --git a/system/gd/os/linux_generic/alarm_unittest.cc b/system/gd/os/linux_generic/alarm_unittest.cc
index f5c14dc410..14b97022b9 100644
--- a/system/gd/os/linux_generic/alarm_unittest.cc
+++ b/system/gd/os/linux_generic/alarm_unittest.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/os/linux_generic/files.cc b/system/gd/os/linux_generic/files.cc
index a759e1d631..045c02c471 100644
--- a/system/gd/os/linux_generic/files.cc
+++ b/system/gd/os/linux_generic/files.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/os/linux_generic/files_test.cc b/system/gd/os/linux_generic/files_test.cc
index 5d85d76fba..5804148c21 100644
--- a/system/gd/os/linux_generic/files_test.cc
+++ b/system/gd/os/linux_generic/files_test.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/os/linux_generic/linux.h b/system/gd/os/linux_generic/linux.h
index b0571355f9..1ef54967ab 100644
--- a/system/gd/os/linux_generic/linux.h
+++ b/system/gd/os/linux_generic/linux.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/os/linux_generic/mgmt.cc b/system/gd/os/linux_generic/mgmt.cc
index 8f2fbd0a17..ebb04b5ed5 100644
--- a/system/gd/os/linux_generic/mgmt.cc
+++ b/system/gd/os/linux_generic/mgmt.cc
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/system/gd/os/linux_generic/queue_unittest.cc b/system/gd/os/linux_generic/queue_unittest.cc
index 0e23454c61..f119a8f734 100644
--- a/system/gd/os/linux_generic/queue_unittest.cc
+++ b/system/gd/os/linux_generic/queue_unittest.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/os/linux_generic/reactive_semaphore.cc b/system/gd/os/linux_generic/reactive_semaphore.cc
index 57fc9d6fe9..76ec29b38b 100644
--- a/system/gd/os/linux_generic/reactive_semaphore.cc
+++ b/system/gd/os/linux_generic/reactive_semaphore.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/os/linux_generic/reactive_semaphore.h b/system/gd/os/linux_generic/reactive_semaphore.h
index ac10d76143..6b92200274 100644
--- a/system/gd/os/linux_generic/reactive_semaphore.h
+++ b/system/gd/os/linux_generic/reactive_semaphore.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/os/linux_generic/reactor.cc b/system/gd/os/linux_generic/reactor.cc
index 13f14dceb1..e67c1fd388 100644
--- a/system/gd/os/linux_generic/reactor.cc
+++ b/system/gd/os/linux_generic/reactor.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/os/linux_generic/reactor_unittest.cc b/system/gd/os/linux_generic/reactor_unittest.cc
index d131f5f74d..326ff1dd33 100644
--- a/system/gd/os/linux_generic/reactor_unittest.cc
+++ b/system/gd/os/linux_generic/reactor_unittest.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/os/linux_generic/repeating_alarm.cc b/system/gd/os/linux_generic/repeating_alarm.cc
index 20542228d4..f2536ba821 100644
--- a/system/gd/os/linux_generic/repeating_alarm.cc
+++ b/system/gd/os/linux_generic/repeating_alarm.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/os/linux_generic/repeating_alarm_unittest.cc b/system/gd/os/linux_generic/repeating_alarm_unittest.cc
index f101f505c9..1868615c84 100644
--- a/system/gd/os/linux_generic/repeating_alarm_unittest.cc
+++ b/system/gd/os/linux_generic/repeating_alarm_unittest.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/os/linux_generic/thread.cc b/system/gd/os/linux_generic/thread.cc
index 33dfb2a229..5799ec096c 100644
--- a/system/gd/os/linux_generic/thread.cc
+++ b/system/gd/os/linux_generic/thread.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/os/linux_generic/thread_unittest.cc b/system/gd/os/linux_generic/thread_unittest.cc
index 9057934845..08160972d4 100644
--- a/system/gd/os/linux_generic/thread_unittest.cc
+++ b/system/gd/os/linux_generic/thread_unittest.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/os/metrics.h b/system/gd/os/metrics.h
index 9f372b25af..aab82826e6 100644
--- a/system/gd/os/metrics.h
+++ b/system/gd/os/metrics.h
@@ -260,11 +260,17 @@ void LogMetricSdpAttribute(const hci::Address& address, uint16_t protocol_uuid,
* by |server_port|
* @param socket_role role of this socket, server or connection
* @param uid socket owner's uid
+ * @param connection_duration_ms duration of socket connection in milliseconds
+ * @param error_code error code of socket failures
+ * @param is_hardware_offload whether this is a offload socket
*/
void LogMetricSocketConnectionState(const hci::Address& address, int port, int type,
android::bluetooth::SocketConnectionstateEnum connection_state,
int64_t tx_bytes, int64_t rx_bytes, int uid, int server_port,
- android::bluetooth::SocketRoleEnum socket_role);
+ android::bluetooth::SocketRoleEnum socket_role,
+ uint64_t connection_duration_ms,
+ android::bluetooth::SocketErrorEnum error_code,
+ bool is_hardware_offload);
/**
* Logs when a Bluetooth device's manufacturer information is learnt
diff --git a/system/gd/os/mock_queue.h b/system/gd/os/mock_queue.h
index 03ede2025b..187911174b 100644
--- a/system/gd/os/mock_queue.h
+++ b/system/gd/os/mock_queue.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2021 The Android Open Source Project
+ * Copyright (C) 2021 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.
diff --git a/system/gd/os/parameter_provider.h b/system/gd/os/parameter_provider.h
index df8a8ee900..e943d9ab37 100644
--- a/system/gd/os/parameter_provider.h
+++ b/system/gd/os/parameter_provider.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/os/queue.h b/system/gd/os/queue.h
index fef9073202..1287ad4f39 100644
--- a/system/gd/os/queue.h
+++ b/system/gd/os/queue.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/os/queue_benchmark.cc b/system/gd/os/queue_benchmark.cc
index b4c442e7dd..c6dfdc9ec1 100644
--- a/system/gd/os/queue_benchmark.cc
+++ b/system/gd/os/queue_benchmark.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/os/rand.h b/system/gd/os/rand.h
index 03f29bc815..d0ab6db36b 100644
--- a/system/gd/os/rand.h
+++ b/system/gd/os/rand.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/os/reactor.h b/system/gd/os/reactor.h
index ef286fbb60..41ad1910a9 100644
--- a/system/gd/os/reactor.h
+++ b/system/gd/os/reactor.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/os/repeating_alarm.h b/system/gd/os/repeating_alarm.h
index d38e5374d0..4ffbc92cd5 100644
--- a/system/gd/os/repeating_alarm.h
+++ b/system/gd/os/repeating_alarm.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/os/system_properties.h b/system/gd/os/system_properties.h
index db31708480..e040119b3e 100644
--- a/system/gd/os/system_properties.h
+++ b/system/gd/os/system_properties.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/os/system_properties_common.cc b/system/gd/os/system_properties_common.cc
index 9dfed10da6..9a491d1a4d 100644
--- a/system/gd/os/system_properties_common.cc
+++ b/system/gd/os/system_properties_common.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/system/gd/os/system_properties_common_test.cc b/system/gd/os/system_properties_common_test.cc
index 1550e0ad19..567995336e 100644
--- a/system/gd/os/system_properties_common_test.cc
+++ b/system/gd/os/system_properties_common_test.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/os/thread.h b/system/gd/os/thread.h
index ccab6113cc..d987195b6c 100644
--- a/system/gd/os/thread.h
+++ b/system/gd/os/thread.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/os/thread_benchmark.cc b/system/gd/os/thread_benchmark.cc
index 529eb8a662..e0dcb008e4 100644
--- a/system/gd/os/thread_benchmark.cc
+++ b/system/gd/os/thread_benchmark.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/os/utils.h b/system/gd/os/utils.h
index f768a317d7..d0fa4e7b64 100644
--- a/system/gd/os/utils.h
+++ b/system/gd/os/utils.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/base_packet_builder.h b/system/gd/packet/base_packet_builder.h
index 766e896f9d..37f0f0e236 100644
--- a/system/gd/packet/base_packet_builder.h
+++ b/system/gd/packet/base_packet_builder.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/base_struct.h b/system/gd/packet/base_struct.h
index f0461f9ff5..a378a05d22 100644
--- a/system/gd/packet/base_struct.h
+++ b/system/gd/packet/base_struct.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/bit_inserter.cc b/system/gd/packet/bit_inserter.cc
index d02e1deecf..4206c4a9ec 100644
--- a/system/gd/packet/bit_inserter.cc
+++ b/system/gd/packet/bit_inserter.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/bit_inserter.h b/system/gd/packet/bit_inserter.h
index f7749d62c6..e0fb8faac4 100644
--- a/system/gd/packet/bit_inserter.h
+++ b/system/gd/packet/bit_inserter.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/bit_inserter_unittest.cc b/system/gd/packet/bit_inserter_unittest.cc
index 636fa470bd..19fc09191c 100644
--- a/system/gd/packet/bit_inserter_unittest.cc
+++ b/system/gd/packet/bit_inserter_unittest.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/byte_inserter.cc b/system/gd/packet/byte_inserter.cc
index a821477a85..cbe04fb172 100644
--- a/system/gd/packet/byte_inserter.cc
+++ b/system/gd/packet/byte_inserter.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/byte_inserter.h b/system/gd/packet/byte_inserter.h
index 9cb71b2e36..150bc37d27 100644
--- a/system/gd/packet/byte_inserter.h
+++ b/system/gd/packet/byte_inserter.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/byte_observer.cc b/system/gd/packet/byte_observer.cc
index 1b294b4bcc..34920b7ac7 100644
--- a/system/gd/packet/byte_observer.cc
+++ b/system/gd/packet/byte_observer.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/byte_observer.h b/system/gd/packet/byte_observer.h
index f5c32f3d66..c700aa18ef 100644
--- a/system/gd/packet/byte_observer.h
+++ b/system/gd/packet/byte_observer.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/checksum_type_checker.h b/system/gd/packet/checksum_type_checker.h
index 380c4d3240..9aeb215c68 100644
--- a/system/gd/packet/checksum_type_checker.h
+++ b/system/gd/packet/checksum_type_checker.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/custom_field_fixed_size_interface.h b/system/gd/packet/custom_field_fixed_size_interface.h
index 1bf1335d27..ce27438948 100644
--- a/system/gd/packet/custom_field_fixed_size_interface.h
+++ b/system/gd/packet/custom_field_fixed_size_interface.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/packet/custom_type_checker.h b/system/gd/packet/custom_type_checker.h
index ea1b59f801..0f6a271789 100644
--- a/system/gd/packet/custom_type_checker.h
+++ b/system/gd/packet/custom_type_checker.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/endian_inserter.h b/system/gd/packet/endian_inserter.h
index 6490ed257c..670d13af15 100644
--- a/system/gd/packet/endian_inserter.h
+++ b/system/gd/packet/endian_inserter.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/fragmenting_inserter.cc b/system/gd/packet/fragmenting_inserter.cc
index a0230c5218..1f552b4eac 100644
--- a/system/gd/packet/fragmenting_inserter.cc
+++ b/system/gd/packet/fragmenting_inserter.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/fragmenting_inserter.h b/system/gd/packet/fragmenting_inserter.h
index 282b6cc228..2073ea967a 100644
--- a/system/gd/packet/fragmenting_inserter.h
+++ b/system/gd/packet/fragmenting_inserter.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/fragmenting_inserter_unittest.cc b/system/gd/packet/fragmenting_inserter_unittest.cc
index 5d90a5a075..b4aa6f573d 100644
--- a/system/gd/packet/fragmenting_inserter_unittest.cc
+++ b/system/gd/packet/fragmenting_inserter_unittest.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/iterator.cc b/system/gd/packet/iterator.cc
index 3b4d48ea4c..0394641335 100644
--- a/system/gd/packet/iterator.cc
+++ b/system/gd/packet/iterator.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/iterator.h b/system/gd/packet/iterator.h
index d1ea14b687..bd724dd96c 100644
--- a/system/gd/packet/iterator.h
+++ b/system/gd/packet/iterator.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/packet_builder.h b/system/gd/packet/packet_builder.h
index 19a0be1183..b772770a9d 100644
--- a/system/gd/packet/packet_builder.h
+++ b/system/gd/packet/packet_builder.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/packet_builder_unittest.cc b/system/gd/packet/packet_builder_unittest.cc
index edb978d7de..8626b86d6e 100644
--- a/system/gd/packet/packet_builder_unittest.cc
+++ b/system/gd/packet/packet_builder_unittest.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/packet_struct.h b/system/gd/packet/packet_struct.h
index 92ab83e4db..cb972f6b1c 100644
--- a/system/gd/packet/packet_struct.h
+++ b/system/gd/packet/packet_struct.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/packet_view.cc b/system/gd/packet/packet_view.cc
index d9d4b86683..e4f44122e5 100644
--- a/system/gd/packet/packet_view.cc
+++ b/system/gd/packet/packet_view.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/packet_view.h b/system/gd/packet/packet_view.h
index 3c495f3755..c9dafb931b 100644
--- a/system/gd/packet/packet_view.h
+++ b/system/gd/packet/packet_view.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/packet_view_unittest.cc b/system/gd/packet/packet_view_unittest.cc
index 108275f94a..3842107fea 100644
--- a/system/gd/packet/packet_view_unittest.cc
+++ b/system/gd/packet/packet_view_unittest.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/checksum_def.cc b/system/gd/packet/parser/checksum_def.cc
index 0ad6ec6f90..6d34e5a581 100644
--- a/system/gd/packet/parser/checksum_def.cc
+++ b/system/gd/packet/parser/checksum_def.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/checksum_def.h b/system/gd/packet/parser/checksum_def.h
index ee8ea1b909..32a57d9eb7 100644
--- a/system/gd/packet/parser/checksum_def.h
+++ b/system/gd/packet/parser/checksum_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/custom_field_def.cc b/system/gd/packet/parser/custom_field_def.cc
index 1ffde0522e..22b3ceaf49 100644
--- a/system/gd/packet/parser/custom_field_def.cc
+++ b/system/gd/packet/parser/custom_field_def.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/custom_field_def.h b/system/gd/packet/parser/custom_field_def.h
index f605fe559b..10eee4af81 100644
--- a/system/gd/packet/parser/custom_field_def.h
+++ b/system/gd/packet/parser/custom_field_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/declarations.h b/system/gd/packet/parser/declarations.h
index ff89d8aaf1..e18b47666d 100644
--- a/system/gd/packet/parser/declarations.h
+++ b/system/gd/packet/parser/declarations.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/enum_def.cc b/system/gd/packet/parser/enum_def.cc
index 8b36572b3a..999ce9cedc 100644
--- a/system/gd/packet/parser/enum_def.cc
+++ b/system/gd/packet/parser/enum_def.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/enum_def.h b/system/gd/packet/parser/enum_def.h
index 1150da86c7..03c0017669 100644
--- a/system/gd/packet/parser/enum_def.h
+++ b/system/gd/packet/parser/enum_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/enum_gen.cc b/system/gd/packet/parser/enum_gen.cc
index b7db3d6b29..f70e8ad449 100644
--- a/system/gd/packet/parser/enum_gen.cc
+++ b/system/gd/packet/parser/enum_gen.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/enum_gen.h b/system/gd/packet/parser/enum_gen.h
index 7dcb7b76a3..d0909f3f4d 100644
--- a/system/gd/packet/parser/enum_gen.h
+++ b/system/gd/packet/parser/enum_gen.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/field_list.h b/system/gd/packet/parser/field_list.h
index 2eaeffa1cb..49cdb23755 100644
--- a/system/gd/packet/parser/field_list.h
+++ b/system/gd/packet/parser/field_list.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/fields/all_fields.h b/system/gd/packet/parser/fields/all_fields.h
index 8c0aeee02f..f750098a1d 100644
--- a/system/gd/packet/parser/fields/all_fields.h
+++ b/system/gd/packet/parser/fields/all_fields.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/fields/array_field.cc b/system/gd/packet/parser/fields/array_field.cc
index b3612a089b..3d6869234e 100644
--- a/system/gd/packet/parser/fields/array_field.cc
+++ b/system/gd/packet/parser/fields/array_field.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/fields/array_field.h b/system/gd/packet/parser/fields/array_field.h
index 80c08e3b97..144feebb4d 100644
--- a/system/gd/packet/parser/fields/array_field.h
+++ b/system/gd/packet/parser/fields/array_field.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/fields/body_field.cc b/system/gd/packet/parser/fields/body_field.cc
index b0a093d7d4..16608d4496 100644
--- a/system/gd/packet/parser/fields/body_field.cc
+++ b/system/gd/packet/parser/fields/body_field.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/fields/body_field.h b/system/gd/packet/parser/fields/body_field.h
index 7f44d001e1..0777f80903 100644
--- a/system/gd/packet/parser/fields/body_field.h
+++ b/system/gd/packet/parser/fields/body_field.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/fields/checksum_field.cc b/system/gd/packet/parser/fields/checksum_field.cc
index 729266ae9d..6a64143bb6 100644
--- a/system/gd/packet/parser/fields/checksum_field.cc
+++ b/system/gd/packet/parser/fields/checksum_field.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/fields/checksum_field.h b/system/gd/packet/parser/fields/checksum_field.h
index c54439b343..c3753382a9 100644
--- a/system/gd/packet/parser/fields/checksum_field.h
+++ b/system/gd/packet/parser/fields/checksum_field.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/fields/checksum_start_field.cc b/system/gd/packet/parser/fields/checksum_start_field.cc
index 3634b45c0f..c5b90f577d 100644
--- a/system/gd/packet/parser/fields/checksum_start_field.cc
+++ b/system/gd/packet/parser/fields/checksum_start_field.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/fields/checksum_start_field.h b/system/gd/packet/parser/fields/checksum_start_field.h
index d0d29ca517..d873c3e889 100644
--- a/system/gd/packet/parser/fields/checksum_start_field.h
+++ b/system/gd/packet/parser/fields/checksum_start_field.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/fields/count_field.cc b/system/gd/packet/parser/fields/count_field.cc
index 0c5c1ace85..7dd2a6a322 100644
--- a/system/gd/packet/parser/fields/count_field.cc
+++ b/system/gd/packet/parser/fields/count_field.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/fields/count_field.h b/system/gd/packet/parser/fields/count_field.h
index d5e3927e95..c145c481fb 100644
--- a/system/gd/packet/parser/fields/count_field.h
+++ b/system/gd/packet/parser/fields/count_field.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/fields/custom_field.cc b/system/gd/packet/parser/fields/custom_field.cc
index c01d5a15eb..a33a86c7f5 100644
--- a/system/gd/packet/parser/fields/custom_field.cc
+++ b/system/gd/packet/parser/fields/custom_field.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/fields/custom_field.h b/system/gd/packet/parser/fields/custom_field.h
index 9a10479e69..e5f547027f 100644
--- a/system/gd/packet/parser/fields/custom_field.h
+++ b/system/gd/packet/parser/fields/custom_field.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/fields/custom_field_fixed_size.cc b/system/gd/packet/parser/fields/custom_field_fixed_size.cc
index 84cffa7986..8419d0b58b 100644
--- a/system/gd/packet/parser/fields/custom_field_fixed_size.cc
+++ b/system/gd/packet/parser/fields/custom_field_fixed_size.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/fields/custom_field_fixed_size.h b/system/gd/packet/parser/fields/custom_field_fixed_size.h
index a5f728286e..05c16fde68 100644
--- a/system/gd/packet/parser/fields/custom_field_fixed_size.h
+++ b/system/gd/packet/parser/fields/custom_field_fixed_size.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/fields/enum_field.cc b/system/gd/packet/parser/fields/enum_field.cc
index 675232d568..f6a46719b8 100644
--- a/system/gd/packet/parser/fields/enum_field.cc
+++ b/system/gd/packet/parser/fields/enum_field.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/fields/enum_field.h b/system/gd/packet/parser/fields/enum_field.h
index ea1a48f3ee..d961824e7e 100644
--- a/system/gd/packet/parser/fields/enum_field.h
+++ b/system/gd/packet/parser/fields/enum_field.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/fields/fixed_enum_field.cc b/system/gd/packet/parser/fields/fixed_enum_field.cc
index 642c46fd4a..a3460df65e 100644
--- a/system/gd/packet/parser/fields/fixed_enum_field.cc
+++ b/system/gd/packet/parser/fields/fixed_enum_field.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/fields/fixed_enum_field.h b/system/gd/packet/parser/fields/fixed_enum_field.h
index 4ea33db12b..31873c6bc3 100644
--- a/system/gd/packet/parser/fields/fixed_enum_field.h
+++ b/system/gd/packet/parser/fields/fixed_enum_field.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/fields/fixed_field.cc b/system/gd/packet/parser/fields/fixed_field.cc
index a5dcd372fa..a15c7e4cac 100644
--- a/system/gd/packet/parser/fields/fixed_field.cc
+++ b/system/gd/packet/parser/fields/fixed_field.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/fields/fixed_field.h b/system/gd/packet/parser/fields/fixed_field.h
index da67daf4e6..4f6da5e6d6 100644
--- a/system/gd/packet/parser/fields/fixed_field.h
+++ b/system/gd/packet/parser/fields/fixed_field.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/fields/fixed_scalar_field.cc b/system/gd/packet/parser/fields/fixed_scalar_field.cc
index 4f66ddb4b7..1cf4ec7d4d 100644
--- a/system/gd/packet/parser/fields/fixed_scalar_field.cc
+++ b/system/gd/packet/parser/fields/fixed_scalar_field.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/fields/fixed_scalar_field.h b/system/gd/packet/parser/fields/fixed_scalar_field.h
index fc6603ad37..ac1afdc892 100644
--- a/system/gd/packet/parser/fields/fixed_scalar_field.h
+++ b/system/gd/packet/parser/fields/fixed_scalar_field.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/fields/group_field.cc b/system/gd/packet/parser/fields/group_field.cc
index 1440d23293..c9c4ce5681 100644
--- a/system/gd/packet/parser/fields/group_field.cc
+++ b/system/gd/packet/parser/fields/group_field.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/fields/group_field.h b/system/gd/packet/parser/fields/group_field.h
index d1f0bee5c5..749a7539c4 100644
--- a/system/gd/packet/parser/fields/group_field.h
+++ b/system/gd/packet/parser/fields/group_field.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/fields/packet_field.cc b/system/gd/packet/parser/fields/packet_field.cc
index 04239ade66..f83c68e4e9 100644
--- a/system/gd/packet/parser/fields/packet_field.cc
+++ b/system/gd/packet/parser/fields/packet_field.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/fields/packet_field.h b/system/gd/packet/parser/fields/packet_field.h
index 4e25c9017e..22194d7fc1 100644
--- a/system/gd/packet/parser/fields/packet_field.h
+++ b/system/gd/packet/parser/fields/packet_field.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/fields/padding_field.cc b/system/gd/packet/parser/fields/padding_field.cc
index d38148eb92..7f92b6c83a 100644
--- a/system/gd/packet/parser/fields/padding_field.cc
+++ b/system/gd/packet/parser/fields/padding_field.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/fields/padding_field.h b/system/gd/packet/parser/fields/padding_field.h
index b9c5449a04..75ef037b5c 100644
--- a/system/gd/packet/parser/fields/padding_field.h
+++ b/system/gd/packet/parser/fields/padding_field.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/fields/payload_field.cc b/system/gd/packet/parser/fields/payload_field.cc
index 85d17b81b7..9f5c3c25a7 100644
--- a/system/gd/packet/parser/fields/payload_field.cc
+++ b/system/gd/packet/parser/fields/payload_field.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/fields/payload_field.h b/system/gd/packet/parser/fields/payload_field.h
index 6ef419d863..17aa1c07ff 100644
--- a/system/gd/packet/parser/fields/payload_field.h
+++ b/system/gd/packet/parser/fields/payload_field.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/fields/reserved_field.cc b/system/gd/packet/parser/fields/reserved_field.cc
index 72b7f25601..a57c9855b7 100644
--- a/system/gd/packet/parser/fields/reserved_field.cc
+++ b/system/gd/packet/parser/fields/reserved_field.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/fields/reserved_field.h b/system/gd/packet/parser/fields/reserved_field.h
index 258ce234af..a658c2067a 100644
--- a/system/gd/packet/parser/fields/reserved_field.h
+++ b/system/gd/packet/parser/fields/reserved_field.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/fields/scalar_field.cc b/system/gd/packet/parser/fields/scalar_field.cc
index f916329cc1..b65e8bd8f7 100644
--- a/system/gd/packet/parser/fields/scalar_field.cc
+++ b/system/gd/packet/parser/fields/scalar_field.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/fields/scalar_field.h b/system/gd/packet/parser/fields/scalar_field.h
index a63d46dd21..802e6f4db1 100644
--- a/system/gd/packet/parser/fields/scalar_field.h
+++ b/system/gd/packet/parser/fields/scalar_field.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/fields/size_field.cc b/system/gd/packet/parser/fields/size_field.cc
index 6c0fbb5360..44c3418c55 100644
--- a/system/gd/packet/parser/fields/size_field.cc
+++ b/system/gd/packet/parser/fields/size_field.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/fields/size_field.h b/system/gd/packet/parser/fields/size_field.h
index 9258a45752..1bd258fee6 100644
--- a/system/gd/packet/parser/fields/size_field.h
+++ b/system/gd/packet/parser/fields/size_field.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/fields/struct_field.cc b/system/gd/packet/parser/fields/struct_field.cc
index 50762045e3..10e3bd26b6 100644
--- a/system/gd/packet/parser/fields/struct_field.cc
+++ b/system/gd/packet/parser/fields/struct_field.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/fields/struct_field.h b/system/gd/packet/parser/fields/struct_field.h
index cb05169c28..e2dd1e7c8f 100644
--- a/system/gd/packet/parser/fields/struct_field.h
+++ b/system/gd/packet/parser/fields/struct_field.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/fields/variable_length_struct_field.cc b/system/gd/packet/parser/fields/variable_length_struct_field.cc
index 0ba48e8800..f114af50bf 100644
--- a/system/gd/packet/parser/fields/variable_length_struct_field.cc
+++ b/system/gd/packet/parser/fields/variable_length_struct_field.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/fields/variable_length_struct_field.h b/system/gd/packet/parser/fields/variable_length_struct_field.h
index 361b7fdca8..34cb38380c 100644
--- a/system/gd/packet/parser/fields/variable_length_struct_field.h
+++ b/system/gd/packet/parser/fields/variable_length_struct_field.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/fields/vector_field.cc b/system/gd/packet/parser/fields/vector_field.cc
index 741bcff32f..ca620247da 100644
--- a/system/gd/packet/parser/fields/vector_field.cc
+++ b/system/gd/packet/parser/fields/vector_field.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/fields/vector_field.h b/system/gd/packet/parser/fields/vector_field.h
index 8ef1155540..c371a731c4 100644
--- a/system/gd/packet/parser/fields/vector_field.h
+++ b/system/gd/packet/parser/fields/vector_field.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/gen_cpp.cc b/system/gd/packet/parser/gen_cpp.cc
index 7dd2deee07..5227c14001 100644
--- a/system/gd/packet/parser/gen_cpp.cc
+++ b/system/gd/packet/parser/gen_cpp.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/logging.h b/system/gd/packet/parser/logging.h
index 0f1f6f1428..6ccaf7d713 100644
--- a/system/gd/packet/parser/logging.h
+++ b/system/gd/packet/parser/logging.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/main.cc b/system/gd/packet/parser/main.cc
index 4426f748f8..cfe585c402 100644
--- a/system/gd/packet/parser/main.cc
+++ b/system/gd/packet/parser/main.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/packet_def.cc b/system/gd/packet/parser/packet_def.cc
index 7753d37547..0d067a371b 100644
--- a/system/gd/packet/parser/packet_def.cc
+++ b/system/gd/packet/parser/packet_def.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/packet_def.h b/system/gd/packet/parser/packet_def.h
index 2ca40975ff..1959c4c267 100644
--- a/system/gd/packet/parser/packet_def.h
+++ b/system/gd/packet/parser/packet_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/packet_dependency.cc b/system/gd/packet/parser/packet_dependency.cc
index 01000ea1ae..ae4c690522 100644
--- a/system/gd/packet/parser/packet_dependency.cc
+++ b/system/gd/packet/parser/packet_dependency.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/system/gd/packet/parser/packet_dependency.h b/system/gd/packet/parser/packet_dependency.h
index ad2a5aa024..2e275e6242 100644
--- a/system/gd/packet/parser/packet_dependency.h
+++ b/system/gd/packet/parser/packet_dependency.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/system/gd/packet/parser/parent_def.cc b/system/gd/packet/parser/parent_def.cc
index 18fd9a98ba..416ee76ea1 100644
--- a/system/gd/packet/parser/parent_def.cc
+++ b/system/gd/packet/parser/parent_def.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/parent_def.h b/system/gd/packet/parser/parent_def.h
index c7816da45b..acaf202d11 100644
--- a/system/gd/packet/parser/parent_def.h
+++ b/system/gd/packet/parser/parent_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/parse_location.h b/system/gd/packet/parser/parse_location.h
index ee2b747888..a3283ab71c 100644
--- a/system/gd/packet/parser/parse_location.h
+++ b/system/gd/packet/parser/parse_location.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/size.h b/system/gd/packet/parser/size.h
index f863639e36..493e4ae949 100644
--- a/system/gd/packet/parser/size.h
+++ b/system/gd/packet/parser/size.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/struct_def.cc b/system/gd/packet/parser/struct_def.cc
index b611bc8957..3f13e0537b 100644
--- a/system/gd/packet/parser/struct_def.cc
+++ b/system/gd/packet/parser/struct_def.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/struct_def.h b/system/gd/packet/parser/struct_def.h
index 82bba3446e..a1a9e275b9 100644
--- a/system/gd/packet/parser/struct_def.h
+++ b/system/gd/packet/parser/struct_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/struct_parser_generator.cc b/system/gd/packet/parser/struct_parser_generator.cc
index cd66b31da6..13d894e3c7 100644
--- a/system/gd/packet/parser/struct_parser_generator.cc
+++ b/system/gd/packet/parser/struct_parser_generator.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/struct_parser_generator.h b/system/gd/packet/parser/struct_parser_generator.h
index 1f5f9b1fcd..8120b187c6 100644
--- a/system/gd/packet/parser/struct_parser_generator.h
+++ b/system/gd/packet/parser/struct_parser_generator.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/test/generated_packet_test.cc b/system/gd/packet/parser/test/generated_packet_test.cc
index e706e15bee..61d7ea1299 100644
--- a/system/gd/packet/parser/test/generated_packet_test.cc
+++ b/system/gd/packet/parser/test/generated_packet_test.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/test/simple_sum.h b/system/gd/packet/parser/test/simple_sum.h
index aea9448803..6228a3abff 100644
--- a/system/gd/packet/parser/test/simple_sum.h
+++ b/system/gd/packet/parser/test/simple_sum.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/test/six_bytes.cc b/system/gd/packet/parser/test/six_bytes.cc
index 5122868318..bc5a16e42b 100644
--- a/system/gd/packet/parser/test/six_bytes.cc
+++ b/system/gd/packet/parser/test/six_bytes.cc
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/test/six_bytes.h b/system/gd/packet/parser/test/six_bytes.h
index c8b3ea8293..34bd44b1c5 100644
--- a/system/gd/packet/parser/test/six_bytes.h
+++ b/system/gd/packet/parser/test/six_bytes.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/test/variable.cc b/system/gd/packet/parser/test/variable.cc
index 727d33a392..ff77914d26 100644
--- a/system/gd/packet/parser/test/variable.cc
+++ b/system/gd/packet/parser/test/variable.cc
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/test/variable.h b/system/gd/packet/parser/test/variable.h
index febd3e63f7..c2d4dfabac 100644
--- a/system/gd/packet/parser/test/variable.h
+++ b/system/gd/packet/parser/test/variable.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/type_def.h b/system/gd/packet/parser/type_def.h
index 9aa5c29731..38c9ae4622 100644
--- a/system/gd/packet/parser/type_def.h
+++ b/system/gd/packet/parser/type_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/parser/util.h b/system/gd/packet/parser/util.h
index c65a5dc493..cc7f09330d 100644
--- a/system/gd/packet/parser/util.h
+++ b/system/gd/packet/parser/util.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/raw_builder.cc b/system/gd/packet/raw_builder.cc
index 49ebeed351..46ffe27852 100644
--- a/system/gd/packet/raw_builder.cc
+++ b/system/gd/packet/raw_builder.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/raw_builder.h b/system/gd/packet/raw_builder.h
index 0b17c049d2..28aa291011 100644
--- a/system/gd/packet/raw_builder.h
+++ b/system/gd/packet/raw_builder.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/raw_builder_unittest.cc b/system/gd/packet/raw_builder_unittest.cc
index 07beca80c4..827ad2fc3b 100644
--- a/system/gd/packet/raw_builder_unittest.cc
+++ b/system/gd/packet/raw_builder_unittest.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/view.cc b/system/gd/packet/view.cc
index 672d2f7769..22b3f5c202 100644
--- a/system/gd/packet/view.cc
+++ b/system/gd/packet/view.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/packet/view.h b/system/gd/packet/view.h
index 9ec8c4b1b1..372e2fb837 100644
--- a/system/gd/packet/view.h
+++ b/system/gd/packet/view.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 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.
diff --git a/system/gd/proto/bluetooth/metrics/bluetooth.proto b/system/gd/proto/bluetooth/metrics/bluetooth.proto
index 64eb0eea21..4acad9fe1e 100644
--- a/system/gd/proto/bluetooth/metrics/bluetooth.proto
+++ b/system/gd/proto/bluetooth/metrics/bluetooth.proto
@@ -22,286 +22,10 @@ package bluetooth.metrics.BluetoothMetricsProto;
option java_package = "com.android.bluetooth";
option java_outer_classname = "BluetoothMetricsProto";
-message BluetoothLog {
- // Session information that gets logged for every BT connection.
- repeated BluetoothSession session = 1;
-
- // Session information that gets logged for every Pair event.
- repeated PairEvent pair_event = 2;
-
- // Information for Wake locks.
- repeated WakeEvent wake_event = 3;
-
- // Scan event information.
- repeated ScanEvent scan_event = 4;
-
- // Number of bonded devices.
- optional int32 num_bonded_devices = 5;
-
- // Number of BluetoothSession including discarded ones beyond capacity
- optional int64 num_bluetooth_session = 6;
-
- // Number of PairEvent including discarded ones beyond capacity
- optional int64 num_pair_event = 7;
-
- // Number of WakeEvent including discarded ones beyond capacity
- optional int64 num_wake_event = 8;
-
- // Number of ScanEvent including discarded ones beyond capacity
- optional int64 num_scan_event = 9;
-
- // Statistics about Bluetooth profile connections
- repeated ProfileConnectionStats profile_connection_stats = 10;
-
- // Statistics about Headset profile connections
- repeated HeadsetProfileConnectionStats headset_profile_connection_stats = 11;
-}
-
-// The information about the device.
-message DeviceInfo {
- // Device type.
- enum DeviceType {
- // Type is unknown.
- DEVICE_TYPE_UNKNOWN = 0;
-
- DEVICE_TYPE_BREDR = 1;
-
- DEVICE_TYPE_LE = 2;
-
- DEVICE_TYPE_DUMO = 3;
- }
-
- // Device class
- // https://cs.corp.google.com/#android/packages/modules/Bluetooth/system/stack/include/btm_api.h&q=major_computer.
- optional int32 device_class = 1;
-
- // Device type.
- optional DeviceType device_type = 2;
-}
-
-// Information that gets logged for every Bluetooth connection.
-message BluetoothSession {
- // Type of technology used in the connection.
- enum ConnectionTechnologyType {
- CONNECTION_TECHNOLOGY_TYPE_UNKNOWN = 0;
-
- CONNECTION_TECHNOLOGY_TYPE_LE = 1;
-
- CONNECTION_TECHNOLOGY_TYPE_BREDR = 2;
- }
-
- enum DisconnectReasonType {
- UNKNOWN = 0;
-
- // A metrics dump takes a snapshot of current Bluetooth session and thus
- // is not a real disconnect, but a discontinuation in metrics logging.
- // This enum indicates this situation.
- METRICS_DUMP = 1;
-
- NEXT_START_WITHOUT_END_PREVIOUS = 2;
- }
-
- // Duration of the session.
- optional int64 session_duration_sec = 2;
-
- // Technology type.
- optional ConnectionTechnologyType connection_technology_type = 3;
-
- // Reason for disconnecting.
- optional string disconnect_reason = 4 [deprecated = true];
-
- // The information about the device which it is connected to.
- optional DeviceInfo device_connected_to = 5;
-
- // The information about the RFComm session.
- optional RFCommSession rfcomm_session = 6;
-
- // The information about the A2DP audio session.
- optional A2DPSession a2dp_session = 7;
-
- // Numeric reason for disconnecting as defined in metrics.h
- optional DisconnectReasonType disconnect_reason_type = 8;
-}
-
-message RFCommSession {
- // bytes transmitted.
- optional int32 rx_bytes = 1;
-
- // bytes transmitted.
- optional int32 tx_bytes = 2;
-}
-
-enum A2dpSourceCodec {
- A2DP_SOURCE_CODEC_UNKNOWN = 0;
- A2DP_SOURCE_CODEC_SBC = 1;
- A2DP_SOURCE_CODEC_AAC = 2;
- A2DP_SOURCE_CODEC_APTX = 3;
- A2DP_SOURCE_CODEC_APTX_HD = 4;
- A2DP_SOURCE_CODEC_LDAC = 5;
-}
-
-// Session information that gets logged for A2DP session.
-message A2DPSession {
- // Media timer in milliseconds.
- optional int32 media_timer_min_millis = 1;
-
- // Media timer in milliseconds.
- optional int32 media_timer_max_millis = 2;
-
- // Media timer in milliseconds.
- optional int32 media_timer_avg_millis = 3;
-
- // Buffer overruns count.
- optional int32 buffer_overruns_max_count = 4;
-
- // Buffer overruns total.
- optional int32 buffer_overruns_total = 5;
-
- // Buffer underruns average.
- optional float buffer_underruns_average = 6;
-
- // Buffer underruns count.
- optional int32 buffer_underruns_count = 7;
-
- // Total audio time in this A2DP session
- optional int64 audio_duration_millis = 8;
-
- // Audio codec used in this A2DP session in A2DP source role
- optional A2dpSourceCodec source_codec = 9;
-
- // Whether A2DP offload is enabled in this A2DP session
- optional bool is_a2dp_offload = 10;
-}
-
-message PairEvent {
- // The reason for disconnecting
- // See: packages/modules/Bluetooth/system/stack/include/hcidefs.h, HCI_ERR_CONN_FAILED_ESTABLISHMENT
- optional int32 disconnect_reason = 1;
-
- // Pair event time
- optional int64 event_time_millis = 2; // [(datapol.semantic_type) = ST_TIMESTAMP];
-
- // The information about the device which it is paired to.
- optional DeviceInfo device_paired_with = 3;
-}
-
-message WakeEvent {
- // Information about the wake event type.
- enum WakeEventType {
- UNKNOWN = 0;
- // WakeLock was acquired.
- ACQUIRED = 1;
- // WakeLock was released.
- RELEASED = 2;
- }
-
- // Information about the wake event type.
- optional WakeEventType wake_event_type = 1;
-
- // Initiator of the scan. Only the first three names will be stored.
- // e.g. com.company.app
- optional string requestor = 2;
-
- // Name of the wakelock (e.g. bluedroid_timer).
- optional string name = 3;
-
- // Time of the event.
- optional int64 event_time_millis = 4; // [(datapol.semantic_type) = ST_TIMESTAMP];
-}
-
-message ScanEvent {
- // Scan type.
- enum ScanTechnologyType {
- SCAN_TYPE_UNKNOWN = 0;
-
- SCAN_TECH_TYPE_LE = 1;
-
- SCAN_TECH_TYPE_BREDR = 2;
-
- SCAN_TECH_TYPE_BOTH = 3;
- }
-
- // Scan event type.
- enum ScanEventType {
- // Scan started.
- SCAN_EVENT_START = 0;
- // Scan stopped.
- SCAN_EVENT_STOP = 1;
- }
-
- // Scan event type.
- optional ScanEventType scan_event_type = 1;
-
- // Initiator of the scan. Only the first three names will be stored.
- // e.g. com.company.app
- optional string initiator = 2;
-
- // Technology used for scanning.
- optional ScanTechnologyType scan_technology_type = 3;
-
- // Number of results returned.
- optional int32 number_results = 4;
-
- // Time of the event.
- optional int64 event_time_millis = 5; // [(datapol.semantic_type) = ST_TIMESTAMP];
-}
-
-// Profile IDs defined in BluetoothProfile API class
-// Values must match API class values
-enum ProfileId {
- PROFILE_UNKNOWN = 0;
- HEADSET = 1;
- A2DP = 2;
- HEALTH = 3;
- HID_HOST = 4;
- PAN = 5;
- PBAP = 6;
- GATT = 7;
- GATT_SERVER = 8;
- MAP = 9;
- SAP = 10;
- A2DP_SINK = 11;
- AVRCP_CONTROLLER = 12;
- AVRCP = 13;
- HEADSET_CLIENT = 16;
- PBAP_CLIENT = 17;
- MAP_CLIENT = 18;
- HID_DEVICE = 19;
- OPP = 20;
- HEARING_AID = 21;
-}
-
-// Statistics about Bluetooth profile connections
-message ProfileConnectionStats {
- // Profile id defined in BluetoothProfile.java
- optional ProfileId profile_id = 1;
-
- // Number of times that this profile is connected since last metrics dump
- optional int32 num_times_connected = 2;
-}
-
-enum HeadsetProfileType {
- HEADSET_PROFILE_UNKNOWN = 0;
- HSP = 1;
- HFP = 2;
-}
-
-// Statistics about headset profile connections
-message HeadsetProfileConnectionStats {
- // Type of headset profile connected
- optional HeadsetProfileType headset_profile_type = 1;
-
- // Number of times this type of headset profile is connected
- optional int32 num_times_connected = 2;
-}
-
/**
* Encapsulates Remote Device Information. Needs to be kept consistent with
* BluetoothRemoteDeviceInformation
* in frameworks/proto_logging/stats/atoms/bluetooth/bluetooth_extension_atoms.proto
-*
-* Logged from:
-* packages/modules/Bluetooth
*/
message BluetoothRemoteDeviceInformation {
// SHA256 hashed Bluetooth device name.
diff --git a/system/gd/rust/linux/service/src/interface_manager.rs b/system/gd/rust/linux/service/src/interface_manager.rs
index 116979de0d..62fdbc8638 100644
--- a/system/gd/rust/linux/service/src/interface_manager.rs
+++ b/system/gd/rust/linux/service/src/interface_manager.rs
@@ -1,27 +1,29 @@
-use dbus::{channel::MatchingReceiver, message::MatchRule, nonblock::SyncConnection};
+use dbus::channel::MatchingReceiver;
+use dbus::message::MatchRule;
+use dbus::nonblock::SyncConnection;
use dbus_crossroads::Crossroads;
use dbus_projection::DisconnectWatcher;
use std::sync::{Arc, Mutex};
use tokio::sync::mpsc::{channel, Receiver, Sender};
-use btstack::{
- battery_manager::BatteryManager, battery_provider_manager::BatteryProviderManager,
- bluetooth::Bluetooth, bluetooth_admin::BluetoothAdmin, bluetooth_gatt::BluetoothGatt,
- bluetooth_logging::BluetoothLogging, bluetooth_media::BluetoothMedia,
- bluetooth_qa::BluetoothQA, socket_manager::BluetoothSocketManager, suspend::Suspend,
- APIMessage, BluetoothAPI, Message,
-};
+use btstack::battery_manager::BatteryManager;
+use btstack::battery_provider_manager::BatteryProviderManager;
+use btstack::bluetooth::{Bluetooth, SigData};
+use btstack::bluetooth_admin::BluetoothAdmin;
+use btstack::bluetooth_gatt::BluetoothGatt;
+use btstack::bluetooth_logging::BluetoothLogging;
+use btstack::bluetooth_media::BluetoothMedia;
+use btstack::bluetooth_qa::BluetoothQA;
+use btstack::socket_manager::BluetoothSocketManager;
+use btstack::suspend::Suspend;
+use btstack::{APIMessage, BluetoothAPI};
-use crate::iface_battery_manager;
-use crate::iface_battery_provider_manager;
-use crate::iface_bluetooth;
-use crate::iface_bluetooth_admin;
-use crate::iface_bluetooth_gatt;
-use crate::iface_bluetooth_media;
-use crate::iface_bluetooth_qa;
-use crate::iface_bluetooth_telephony;
-use crate::iface_logging;
+use crate::{
+ iface_battery_manager, iface_battery_provider_manager, iface_bluetooth, iface_bluetooth_admin,
+ iface_bluetooth_gatt, iface_bluetooth_media, iface_bluetooth_qa, iface_bluetooth_telephony,
+ iface_logging,
+};
pub(crate) struct InterfaceManager {}
@@ -50,11 +52,11 @@ impl InterfaceManager {
#[allow(clippy::too_many_arguments)]
pub async fn dispatch(
mut rx: Receiver<APIMessage>,
- tx: Sender<Message>,
virt_index: i32,
conn: Arc<SyncConnection>,
conn_join_handle: tokio::task::JoinHandle<()>,
disconnect_watcher: Arc<Mutex<DisconnectWatcher>>,
+ sig_notifier: Arc<SigData>,
bluetooth: Arc<Mutex<Box<Bluetooth>>>,
bluetooth_admin: Arc<Mutex<Box<BluetoothAdmin>>>,
bluetooth_gatt: Arc<Mutex<Box<BluetoothGatt>>>,
@@ -93,6 +95,9 @@ impl InterfaceManager {
}),
);
+ *sig_notifier.api_enabled.lock().unwrap() = true;
+ sig_notifier.api_notify.notify_all();
+
// Register D-Bus method handlers of IBluetooth.
let adapter_iface = iface_bluetooth::export_bluetooth_dbus_intf(
conn.clone(),
@@ -246,11 +251,8 @@ impl InterfaceManager {
// To shut down the connection, call _handle.abort() and drop the connection.
conn_join_handle.abort();
drop(conn);
-
- let tx = tx.clone();
- tokio::spawn(async move {
- let _ = tx.send(Message::AdapterShutdown).await;
- });
+ *sig_notifier.api_enabled.lock().unwrap() = false;
+ sig_notifier.api_notify.notify_all();
break;
}
}
diff --git a/system/gd/rust/linux/service/src/main.rs b/system/gd/rust/linux/service/src/main.rs
index f326bb62ee..4fc43d11f3 100644
--- a/system/gd/rust/linux/service/src/main.rs
+++ b/system/gd/rust/linux/service/src/main.rs
@@ -9,22 +9,21 @@ use std::time::Duration;
use tokio::runtime::Builder;
use tokio::sync::mpsc::Sender;
-use bt_topshim::{btif::get_btinterface, topstack};
-use btstack::{
- battery_manager::BatteryManager,
- battery_provider_manager::BatteryProviderManager,
- battery_service::BatteryService,
- bluetooth::{Bluetooth, IBluetooth, SigData},
- bluetooth_admin::BluetoothAdmin,
- bluetooth_gatt::BluetoothGatt,
- bluetooth_logging::BluetoothLogging,
- bluetooth_media::BluetoothMedia,
- bluetooth_qa::BluetoothQA,
- dis::DeviceInformation,
- socket_manager::BluetoothSocketManager,
- suspend::Suspend,
- Message, Stack,
-};
+use bt_topshim::btif::get_btinterface;
+use bt_topshim::topstack;
+use btstack::battery_manager::BatteryManager;
+use btstack::battery_provider_manager::BatteryProviderManager;
+use btstack::battery_service::BatteryService;
+use btstack::bluetooth::{Bluetooth, IBluetooth, SigData};
+use btstack::bluetooth_admin::BluetoothAdmin;
+use btstack::bluetooth_gatt::BluetoothGatt;
+use btstack::bluetooth_logging::BluetoothLogging;
+use btstack::bluetooth_media::BluetoothMedia;
+use btstack::bluetooth_qa::BluetoothQA;
+use btstack::dis::DeviceInformation;
+use btstack::socket_manager::BluetoothSocketManager;
+use btstack::suspend::Suspend;
+use btstack::{Message, Stack};
mod dbus_arg;
mod iface_battery_manager;
@@ -40,6 +39,8 @@ mod interface_manager;
const DBUS_SERVICE_NAME: &str = "org.chromium.bluetooth";
const ADMIN_SETTINGS_FILE_PATH: &str = "/var/lib/bluetooth/admin_policy.json";
+// Time to wait for API unregistration in DBus
+const API_DISABLE_TIMEOUT_MS: Duration = Duration::from_millis(100);
// The maximum ACL disconnect timeout is 3.5s defined by BTA_DM_DISABLE_TIMER_MS
// and BTA_DM_DISABLE_TIMER_RETRIAL_MS
const STACK_TURN_OFF_TIMEOUT_MS: Duration = Duration::from_millis(4000);
@@ -115,6 +116,8 @@ fn main() -> Result<(), Box<dyn Error>> {
enabled_notify: Condvar::new(),
thread_attached: Mutex::new(false),
thread_notify: Condvar::new(),
+ api_enabled: Mutex::new(false),
+ api_notify: Condvar::new(),
});
// This needs to be built before any |topstack::get_runtime()| call!
@@ -148,8 +151,14 @@ fn main() -> Result<(), Box<dyn Error>> {
signal::SaFlags::empty(),
signal::SigSet::empty(),
);
+ let sig_action_usr1 = signal::SigAction::new(
+ signal::SigHandler::Handler(handle_sigusr1),
+ signal::SaFlags::empty(),
+ signal::SigSet::empty(),
+ );
unsafe {
signal::sigaction(signal::SIGTERM, &sig_action_term).unwrap();
+ signal::sigaction(signal::SIGUSR1, &sig_action_usr1).unwrap();
}
// Construct btstack profiles.
@@ -241,11 +250,11 @@ fn main() -> Result<(), Box<dyn Error>> {
tokio::spawn(interface_manager::InterfaceManager::dispatch(
api_rx,
- tx.clone(),
virt_index,
conn,
conn_join_handle,
disconnect_watcher.clone(),
+ sig_notifier.clone(),
bluetooth.clone(),
bluetooth_admin.clone(),
bluetooth_gatt.clone(),
@@ -267,37 +276,63 @@ fn main() -> Result<(), Box<dyn Error>> {
/// Data needed for signal handling.
static SIG_DATA: Mutex<Option<(Sender<Message>, Arc<SigData>)>> = Mutex::new(None);
-extern "C" fn handle_sigterm(_signum: i32) {
- let guard = SIG_DATA.lock().unwrap();
- if let Some((tx, notifier)) = guard.as_ref() {
- log::debug!("Handling SIGTERM by disabling the adapter!");
- let txl = tx.clone();
- topstack::get_runtime().spawn(async move {
- // Send the shutdown message here.
- let _ = txl.send(Message::InterfaceShutdown).await;
- });
+/// Try to cleanup the whole stack. Returns whether to clean up.
+extern "C" fn try_cleanup_stack(abort: bool) -> bool {
+ let lock = SIG_DATA.try_lock();
+
+ // If SIG_DATA is locked, it is likely the cleanup procedure is ongoing. No
+ // need to do anything here.
+ if lock.is_err() {
+ return false;
+ }
+
+ if let Some((tx, notifier)) = lock.unwrap().as_ref() {
+ log::info!("Cleanup stack: disabling the adapter!");
+
+ // Remove the API first to prevent clients calling while shutting down.
+ let guard = notifier.api_enabled.lock().unwrap();
+ if *guard {
+ let txl = tx.clone();
+ topstack::get_runtime().spawn(async move {
+ // Remove the API first to prevent clients calling while shutting down.
+ let _ = txl.send(Message::InterfaceShutdown).await;
+ });
+ log::info!(
+ "Cleanup stack: Waiting for API shutdown to complete for {:?}",
+ API_DISABLE_TIMEOUT_MS
+ );
+ let _ = notifier.api_notify.wait_timeout(guard, API_DISABLE_TIMEOUT_MS);
+ }
let guard = notifier.enabled.lock().unwrap();
if *guard {
- log::debug!("Waiting for stack to turn off for {:?}", STACK_TURN_OFF_TIMEOUT_MS);
+ let txl = tx.clone();
+ topstack::get_runtime().spawn(async move {
+ let _ = txl.send(Message::AdapterShutdown(abort)).await;
+ });
+ log::info!(
+ "Cleanup stack: Waiting for stack to turn off for {:?}",
+ STACK_TURN_OFF_TIMEOUT_MS
+ );
let _ = notifier.enabled_notify.wait_timeout(guard, STACK_TURN_OFF_TIMEOUT_MS);
}
- log::debug!("SIGTERM cleaning up the stack.");
- let txl = tx.clone();
- topstack::get_runtime().spawn(async move {
- // Clean up the profiles first as some of them might require main thread to clean up.
- let _ = txl.send(Message::CleanupProfiles).await;
- // Currently there is no good way to know when the profile is cleaned.
- // Simply add a small delay here.
- tokio::time::sleep(STACK_CLEANUP_PROFILES_TIMEOUT_MS).await;
- // Send the cleanup message to clean up the main thread.
- let _ = txl.send(Message::Cleanup).await;
- });
-
let guard = notifier.thread_attached.lock().unwrap();
if *guard {
- log::debug!("Waiting for stack to clean up for {:?}", STACK_CLEANUP_TIMEOUT_MS);
+ let txl = tx.clone();
+ topstack::get_runtime().spawn(async move {
+ // Clean up the profiles first as some of them might require main thread to clean up.
+ let _ = txl.send(Message::CleanupProfiles).await;
+ // Currently there is no good way to know when the profile is cleaned.
+ // Simply add a small delay here.
+ tokio::time::sleep(STACK_CLEANUP_PROFILES_TIMEOUT_MS).await;
+ // Send the cleanup message to clean up the main thread.
+ let _ = txl.send(Message::Cleanup).await;
+ });
+ log::info!(
+ "Cleanup stack: Waiting for libbluetooth stack to clean up for {:?}",
+ STACK_CLEANUP_TIMEOUT_MS
+ );
let _ = notifier.thread_notify.wait_timeout(guard, STACK_CLEANUP_TIMEOUT_MS);
}
@@ -305,7 +340,26 @@ extern "C" fn handle_sigterm(_signum: i32) {
// finishing btif cleanup.
std::thread::sleep(EXTRA_WAIT_BEFORE_KILL_MS);
}
+ return true;
+}
- log::debug!("Sigterm completed");
+extern "C" fn handle_sigterm(_signum: i32) {
+ log::info!("SIGTERM received");
+ if !try_cleanup_stack(false) {
+ log::info!("Skipped to handle SIGTERM");
+ return;
+ }
+ log::info!("SIGTERM completed");
+ std::process::exit(0);
+}
+
+/// Used to indicate controller needs reset
+extern "C" fn handle_sigusr1(_signum: i32) {
+ log::info!("SIGUSR1 received");
+ if !try_cleanup_stack(true) {
+ log::info!("Skipped to handle SIGUSR1");
+ return;
+ }
+ log::info!("SIGUSR1 completed");
std::process::exit(0);
}
diff --git a/system/gd/rust/linux/stack/src/bluetooth.rs b/system/gd/rust/linux/stack/src/bluetooth.rs
index bac9c4a1a9..ade91229c4 100644
--- a/system/gd/rust/linux/stack/src/bluetooth.rs
+++ b/system/gd/rust/linux/stack/src/bluetooth.rs
@@ -503,6 +503,9 @@ pub struct SigData {
pub thread_attached: Mutex<bool>,
pub thread_notify: Condvar,
+
+ pub api_enabled: Mutex<bool>,
+ pub api_notify: Condvar,
}
/// The interface for adapter callbacks registered through `IBluetooth::register_callback`.
@@ -818,6 +821,21 @@ impl Bluetooth {
self.connection_callbacks.remove_callback(id);
}
+ pub fn shutdown_adapter(&mut self, abort: bool) -> bool {
+ self.disabling = true;
+
+ if !abort {
+ if !self.set_discoverable(BtDiscMode::NonDiscoverable, 0) {
+ warn!("set_discoverable failed on disabling");
+ }
+ if !self.set_connectable_internal(false) {
+ warn!("set_connectable_internal failed on disabling");
+ }
+ }
+
+ self.intf.lock().unwrap().disable() == 0
+ }
+
fn get_remote_device_property(
&self,
device: &BluetoothDevice,
@@ -2240,14 +2258,7 @@ impl IBluetooth for Bluetooth {
}
fn disable(&mut self) -> bool {
- self.disabling = true;
- if !self.set_discoverable(BtDiscMode::NonDiscoverable, 0) {
- warn!("set_discoverable failed on disabling");
- }
- if !self.set_connectable_internal(false) {
- warn!("set_connectable_internal failed on disabling");
- }
- self.intf.lock().unwrap().disable() == 0
+ self.shutdown_adapter(false)
}
fn cleanup(&mut self) {
diff --git a/system/gd/rust/linux/stack/src/lib.rs b/system/gd/rust/linux/stack/src/lib.rs
index d9f97bfa32..4f49a186b4 100644
--- a/system/gd/rust/linux/stack/src/lib.rs
+++ b/system/gd/rust/linux/stack/src/lib.rs
@@ -66,7 +66,9 @@ pub enum Message {
/// Remove the DBus API. Call it before other AdapterShutdown.
InterfaceShutdown,
/// Disable the adapter by calling btif disable.
- AdapterShutdown,
+ /// Param: bool to indicate abort(true) or graceful shutdown(false).
+ /// Use abort when we believe adapter is already in a bad state.
+ AdapterShutdown(bool),
/// Clean up the adapter by calling btif cleanup.
Cleanup,
/// Clean up the media by calling profile cleanup.
@@ -287,9 +289,9 @@ impl Stack {
});
}
- Message::AdapterShutdown => {
+ Message::AdapterShutdown(abort) => {
bluetooth_gatt.lock().unwrap().enable(false);
- bluetooth.lock().unwrap().disable();
+ bluetooth.lock().unwrap().shutdown_adapter(abort);
}
Message::Cleanup => {
diff --git a/system/gd/rust/topshim/controller/controller_shim.cc b/system/gd/rust/topshim/controller/controller_shim.cc
index b47065f440..4b587d79b3 100644
--- a/system/gd/rust/topshim/controller/controller_shim.cc
+++ b/system/gd/rust/topshim/controller/controller_shim.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2021 The Android Open Source Project
+ * Copyright (C) 2021 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.
diff --git a/system/gd/storage/classic_device.cc b/system/gd/storage/classic_device.cc
index f2104a9c07..e49e6b214e 100644
--- a/system/gd/storage/classic_device.cc
+++ b/system/gd/storage/classic_device.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/storage/classic_device.h b/system/gd/storage/classic_device.h
index 155b44d8d8..dec4ebceda 100644
--- a/system/gd/storage/classic_device.h
+++ b/system/gd/storage/classic_device.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/storage/classic_device_test.cc b/system/gd/storage/classic_device_test.cc
index ae26587d7a..2dbe9df5d6 100644
--- a/system/gd/storage/classic_device_test.cc
+++ b/system/gd/storage/classic_device_test.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/storage/config_cache.cc b/system/gd/storage/config_cache.cc
index f2517be128..c506c3dcae 100644
--- a/system/gd/storage/config_cache.cc
+++ b/system/gd/storage/config_cache.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/storage/config_cache.h b/system/gd/storage/config_cache.h
index 238660170c..25a3a1b6c3 100644
--- a/system/gd/storage/config_cache.h
+++ b/system/gd/storage/config_cache.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/storage/config_cache_helper.cc b/system/gd/storage/config_cache_helper.cc
index 485ed61508..7c2eb7d630 100644
--- a/system/gd/storage/config_cache_helper.cc
+++ b/system/gd/storage/config_cache_helper.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/storage/config_cache_helper.h b/system/gd/storage/config_cache_helper.h
index e4f5c23a57..2f02c0e0e4 100644
--- a/system/gd/storage/config_cache_helper.h
+++ b/system/gd/storage/config_cache_helper.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/storage/config_cache_helper_test.cc b/system/gd/storage/config_cache_helper_test.cc
index e149c3777c..5ad20e6be0 100644
--- a/system/gd/storage/config_cache_helper_test.cc
+++ b/system/gd/storage/config_cache_helper_test.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/storage/config_cache_test.cc b/system/gd/storage/config_cache_test.cc
index c129e8841b..3aa0bc493d 100644
--- a/system/gd/storage/config_cache_test.cc
+++ b/system/gd/storage/config_cache_test.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/storage/device.cc b/system/gd/storage/device.cc
index 7210a110fe..b84f360477 100644
--- a/system/gd/storage/device.cc
+++ b/system/gd/storage/device.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/storage/device.h b/system/gd/storage/device.h
index 03311d1504..40ca990080 100644
--- a/system/gd/storage/device.h
+++ b/system/gd/storage/device.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/storage/device_test.cc b/system/gd/storage/device_test.cc
index 01754cfd7e..ab8d399db0 100644
--- a/system/gd/storage/device_test.cc
+++ b/system/gd/storage/device_test.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/storage/le_device.cc b/system/gd/storage/le_device.cc
index 3cbbb7839f..bf6475faa8 100644
--- a/system/gd/storage/le_device.cc
+++ b/system/gd/storage/le_device.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/storage/le_device.h b/system/gd/storage/le_device.h
index 835519929e..aa5c4d8815 100644
--- a/system/gd/storage/le_device.h
+++ b/system/gd/storage/le_device.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/storage/le_device_test.cc b/system/gd/storage/le_device_test.cc
index b18b4e2fb7..c32c94f3d3 100644
--- a/system/gd/storage/le_device_test.cc
+++ b/system/gd/storage/le_device_test.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/storage/legacy_config_file.cc b/system/gd/storage/legacy_config_file.cc
index 0bee52af03..29f09da9bd 100644
--- a/system/gd/storage/legacy_config_file.cc
+++ b/system/gd/storage/legacy_config_file.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/storage/legacy_config_file.h b/system/gd/storage/legacy_config_file.h
index 2a5a8bf9b0..0bfa1651b6 100644
--- a/system/gd/storage/legacy_config_file.h
+++ b/system/gd/storage/legacy_config_file.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/storage/legacy_config_file_test.cc b/system/gd/storage/legacy_config_file_test.cc
index b52891793f..1c11ea8ba0 100644
--- a/system/gd/storage/legacy_config_file_test.cc
+++ b/system/gd/storage/legacy_config_file_test.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/storage/mutation.cc b/system/gd/storage/mutation.cc
index e091344f36..097357a668 100644
--- a/system/gd/storage/mutation.cc
+++ b/system/gd/storage/mutation.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/storage/mutation.h b/system/gd/storage/mutation.h
index 4f24e7725b..ec801f13ee 100644
--- a/system/gd/storage/mutation.h
+++ b/system/gd/storage/mutation.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/storage/mutation_entry.cc b/system/gd/storage/mutation_entry.cc
index 5d610e70ef..a3b99afd09 100644
--- a/system/gd/storage/mutation_entry.cc
+++ b/system/gd/storage/mutation_entry.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/storage/mutation_entry.h b/system/gd/storage/mutation_entry.h
index cc1a3d09ed..00ce85bc6c 100644
--- a/system/gd/storage/mutation_entry.h
+++ b/system/gd/storage/mutation_entry.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/storage/mutation_test.cc b/system/gd/storage/mutation_test.cc
index 1a1a3e82ff..c99b3d754f 100644
--- a/system/gd/storage/mutation_test.cc
+++ b/system/gd/storage/mutation_test.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/storage/serializable.h b/system/gd/storage/serializable.h
index ef26d3a4f4..0b617e0d3d 100644
--- a/system/gd/storage/serializable.h
+++ b/system/gd/storage/serializable.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/storage/storage_module.cc b/system/gd/storage/storage_module.cc
index 9a59caf4f6..5e3459e109 100644
--- a/system/gd/storage/storage_module.cc
+++ b/system/gd/storage/storage_module.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/storage/storage_module.h b/system/gd/storage/storage_module.h
index 8899423697..de47e71e25 100644
--- a/system/gd/storage/storage_module.h
+++ b/system/gd/storage/storage_module.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/storage/storage_module_test.cc b/system/gd/storage/storage_module_test.cc
index 488eda0a53..7eaf3ae3fa 100644
--- a/system/gd/storage/storage_module_test.cc
+++ b/system/gd/storage/storage_module_test.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/sysprops/sysprops_module.cc b/system/gd/sysprops/sysprops_module.cc
index 0cdcaa2efa..b994bcf52c 100644
--- a/system/gd/sysprops/sysprops_module.cc
+++ b/system/gd/sysprops/sysprops_module.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/sysprops/sysprops_module.h b/system/gd/sysprops/sysprops_module.h
index d1050bd660..eaeb648941 100644
--- a/system/gd/sysprops/sysprops_module.h
+++ b/system/gd/sysprops/sysprops_module.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2020 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.
diff --git a/system/gd/sysprops/sysprops_module_test.cc b/system/gd/sysprops/sysprops_module_test.cc
index e427db3831..e4f90b9068 100644
--- a/system/gd/sysprops/sysprops_module_test.cc
+++ b/system/gd/sysprops/sysprops_module_test.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 The Android Open Source Project
+ * Copyright (C) 2024 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.
diff --git a/system/include/hardware/bluetooth_headset_interface.h b/system/include/hardware/bluetooth_headset_interface.h
index b2b98ffe1f..396c2b2880 100644
--- a/system/include/hardware/bluetooth_headset_interface.h
+++ b/system/include/hardware/bluetooth_headset_interface.h
@@ -97,9 +97,10 @@ public:
/**
* Start voice recognition
* @param bd_addr remote device address
+ * @param sendResult whether a BVRA response should be sent
* @return BT_STATUS_SUCCESS on success
*/
- virtual bt_status_t StartVoiceRecognition(RawAddress* bd_addr) = 0;
+ virtual bt_status_t StartVoiceRecognition(RawAddress* bd_addr, bool sendResult) = 0;
/**
* Stop voice recognition
diff --git a/system/include/hardware/bt_sock.h b/system/include/hardware/bt_sock.h
index 0436fad9cb..340085998c 100644
--- a/system/include/hardware/bt_sock.h
+++ b/system/include/hardware/bt_sock.h
@@ -38,6 +38,25 @@ typedef enum {
BTSOCK_L2CAP_LE = 4
} btsock_type_t;
+typedef enum {
+ BTSOCK_ERROR_NONE = 0,
+ BTSOCK_ERROR_SERVER_START_FAILURE = 1,
+ BTSOCK_ERROR_CLIENT_INIT_FAILURE = 2,
+ BTSOCK_ERROR_LISTEN_FAILURE = 3,
+ BTSOCK_ERROR_CONNECTION_FAILURE = 4,
+ BTSOCK_ERROR_OPEN_FAILURE = 5,
+ BTSOCK_ERROR_OFFLOAD_SERVER_NOT_ACCEPTING = 6,
+ BTSOCK_ERROR_OFFLOAD_HAL_OPEN_FAILURE = 7,
+ BTSOCK_ERROR_SEND_TO_APP_FAILURE = 8,
+ BTSOCK_ERROR_RECEIVE_DATA_FAILURE = 9,
+ BTSOCK_ERROR_READ_SIGNALED_FAILURE = 10,
+ BTSOCK_ERROR_WRITE_SIGNALED_FAILURE = 11,
+ BTSOCK_ERROR_SEND_SCN_FAILURE = 12,
+ BTSOCK_ERROR_SCN_ALLOCATION_FAILURE = 13,
+ BTSOCK_ERROR_ADD_SDP_FAILURE = 14,
+ BTSOCK_ERROR_SDP_DISCOVERY_FAILURE = 15,
+} btsock_error_code_t;
+
/**
* Data path used for Bluetooth socket communication.
*
diff --git a/system/linux_include/log/log.h b/system/linux_include/log/log.h
deleted file mode 100644
index 037649312c..0000000000
--- a/system/linux_include/log/log.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2018 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.
- *
- ******************************************************************************/
-#pragma once
-
-#ifndef __ANDROID__
-
-#include <cstdint>
-
-#endif
diff --git a/system/main/shim/metrics_api.cc b/system/main/shim/metrics_api.cc
index f222adf82a..2250090901 100644
--- a/system/main/shim/metrics_api.cc
+++ b/system/main/shim/metrics_api.cc
@@ -135,10 +135,14 @@ void LogMetricSdpAttribute(const RawAddress& raw_address, uint16_t protocol_uuid
void LogMetricSocketConnectionState(const RawAddress& raw_address, int port, int type,
android::bluetooth::SocketConnectionstateEnum connection_state,
int64_t tx_bytes, int64_t rx_bytes, int uid, int server_port,
- android::bluetooth::SocketRoleEnum socket_role) {
+ android::bluetooth::SocketRoleEnum socket_role,
+ uint64_t connection_duration_ms,
+ android::bluetooth::SocketErrorEnum error_code,
+ bool is_hardware_offload) {
Address address = bluetooth::ToGdAddress(raw_address);
- bluetooth::os::LogMetricSocketConnectionState(address, port, type, connection_state, tx_bytes,
- rx_bytes, uid, server_port, socket_role);
+ bluetooth::os::LogMetricSocketConnectionState(
+ address, port, type, connection_state, tx_bytes, rx_bytes, uid, server_port, socket_role,
+ connection_duration_ms, error_code, is_hardware_offload);
}
void LogMetricManufacturerInfo(const RawAddress& raw_address,
diff --git a/system/main/shim/metrics_api.h b/system/main/shim/metrics_api.h
index 3b8e369b69..143a2f754d 100644
--- a/system/main/shim/metrics_api.h
+++ b/system/main/shim/metrics_api.h
@@ -225,11 +225,17 @@ void LogMetricSdpAttribute(const RawAddress& address, uint16_t protocol_uuid, ui
* by |server_port|
* @param socket_role role of this socket, server or connection
* @param uid socket owner's uid
+ * @param connection_duration_ms duration of socket connection in milliseconds
+ * @param error_code error code of socket failures
+ * @param is_hardware_offload whether this is a offload socket
*/
void LogMetricSocketConnectionState(const RawAddress& address, int port, int type,
android::bluetooth::SocketConnectionstateEnum connection_state,
int64_t tx_bytes, int64_t rx_bytes, int uid, int server_port,
- android::bluetooth::SocketRoleEnum socket_role);
+ android::bluetooth::SocketRoleEnum socket_role,
+ uint64_t connection_duration_ms,
+ android::bluetooth::SocketErrorEnum error_code,
+ bool is_hardware_offload);
/**
* Logs when a Bluetooth device's manufacturer information is learnt
diff --git a/system/main/shim/stack.cc b/system/main/shim/stack.cc
index bb8994aee0..4560a6180f 100644
--- a/system/main/shim/stack.cc
+++ b/system/main/shim/stack.cc
@@ -169,11 +169,11 @@ void Stack::Stop() {
log::assert_that(is_running_, "Gd stack not running");
is_running_ = false;
- if (!com::android::bluetooth::flags::same_handler_for_all_modules()) {
- // Clear the handler only if the flag is not defined, otherwise it will be cleared by the
- // registry
- stack_handler_->Clear();
+ stack_handler_->Clear();
+ if(com::android::bluetooth::flags::same_handler_for_all_modules()) {
+ stack_handler_->WaitUntilStopped(bluetooth::kHandlerStopTimeout);
}
+
WakelockManager::Get().Acquire();
std::promise<void> promise;
@@ -195,14 +195,7 @@ void Stack::Stop() {
delete management_handler_;
delete management_thread_;
- if (!com::android::bluetooth::flags::same_handler_for_all_modules()) {
- // delete the handler only if the flag is not defined, otherwise it will be deleted by the
- // registry
- delete stack_handler_;
- }
-
- // stack_handler_ is already deleted by the registry in handle_shut_down, just set it to nullptr
- // to avoid any potential use-after-free
+ delete stack_handler_;
stack_handler_ = nullptr;
stack_thread_->Stop();
diff --git a/system/main/test/main_shim_test.cc b/system/main/test/main_shim_test.cc
index 2f4056a381..c66024cabb 100644
--- a/system/main/test/main_shim_test.cc
+++ b/system/main/test/main_shim_test.cc
@@ -332,8 +332,10 @@ protected:
thread_ = new os::Thread("acl_thread", os::Thread::Priority::NORMAL);
handler_ = new os::Handler(thread_);
- /* extern */ test::mock_controller_ = new bluetooth::hci::testing::MockControllerInterface();
- /* extern */ test::mock_acl_manager_ = new bluetooth::hci::testing::MockAclManager();
+ /* extern */ test::mock_controller_ =
+ std::make_unique<bluetooth::hci::testing::MockControllerInterface>();
+ /* extern */ test::mock_acl_manager_ =
+ std::make_unique<bluetooth::hci::testing::MockAclManager>();
/* extern */ test::mock_le_scanning_manager_ =
new bluetooth::hci::testing::MockLeScanningManager();
/* extern */ test::mock_le_advertising_manager_ =
@@ -342,10 +344,8 @@ protected:
new bluetooth::hci::testing::MockDistanceMeasurementManager();
}
void TearDown() override {
- delete test::mock_controller_;
- test::mock_controller_ = nullptr;
- delete test::mock_acl_manager_;
- test::mock_acl_manager_ = nullptr;
+ test::mock_controller_.reset();
+ test::mock_acl_manager_.release();
delete test::mock_le_advertising_manager_;
test::mock_le_advertising_manager_ = nullptr;
delete test::mock_le_scanning_manager_;
@@ -567,7 +567,6 @@ TEST_F(MainShimTest, DISABLED_BleScannerInterfaceImpl_OnScanResult) {
bluetooth::shim::get_ble_scanner_instance());
EXPECT_CALL(*hci::testing::mock_le_scanning_manager_, RegisterScanningCallback(_)).Times(1);
- ;
bluetooth::shim::init_scanning_manager();
TestScanningCallbacks cb;
diff --git a/system/osi/BUILD.gn b/system/osi/BUILD.gn
index 5bdf04c1e9..fa47062f52 100644
--- a/system/osi/BUILD.gn
+++ b/system/osi/BUILD.gn
@@ -43,7 +43,6 @@ static_library("osi") {
include_dirs = [
"//bt/system/",
- "//bt/system/linux_include",
"//bt/system/osi/include_internal",
"//bt/system/stack/include",
]
diff --git a/system/pdl/hci/hci_packets.pdl b/system/pdl/hci/hci_packets.pdl
index fcdd255b99..838b1fa586 100644
--- a/system/pdl/hci/hci_packets.pdl
+++ b/system/pdl/hci/hci_packets.pdl
@@ -4949,7 +4949,8 @@ struct CsOptionalNadmRandomCapability {
struct CsOptionalCsSyncPhysSupported {
le_2m_phy : 1,
- _reserved_ : 7,
+ le_2m_2bt_phy : 1,
+ _reserved_ : 6,
}
struct CsOptionalSubfeaturesSupported {
@@ -5151,6 +5152,7 @@ enum CsConfigRttType : 8 {
enum CsSyncPhy : 8 {
LE_1M_PHY = 0x01,
LE_2M_PHY = 0x02,
+ LE_2M_2BT_PHY = 0x03,
}
enum CsChannelSelectionType : 8 {
diff --git a/system/stack/Android.bp b/system/stack/Android.bp
index ebab1ff5f4..78af467a76 100644
--- a/system/stack/Android.bp
+++ b/system/stack/Android.bp
@@ -48,7 +48,6 @@ cc_library_static {
"hid",
"include",
"l2cap",
- "metrics",
"pan",
"sdp",
"smp",
@@ -183,7 +182,6 @@ cc_library_static {
"l2cap/l2c_main.cc",
"l2cap/l2c_utils.cc",
"l2cap/l2cap_api.cc",
- "metrics/stack_metrics_logging.cc",
"pan/pan_api.cc",
"pan/pan_main.cc",
"pan/pan_utils.cc",
@@ -374,9 +372,9 @@ cc_fuzz {
":TestFakeOsi",
":TestMockBtif",
":TestMockDevice",
+ ":TestMockMainShim",
":TestMockStackBtm",
":TestMockStackL2cap",
- ":TestMockStackMetrics",
"fuzzers/sdp_fuzzer.cc",
],
static_libs: [
@@ -414,6 +412,7 @@ cc_fuzz {
":TestMockBtif",
":TestMockDevice",
":TestMockMainShim",
+ ":TestMockMainShim",
":TestMockMainShimEntry",
":TestMockSrvcDis",
":TestMockStackAcl",
@@ -421,7 +420,6 @@ cc_fuzz {
":TestMockStackBtm",
":TestMockStackHcic",
":TestMockStackL2cap",
- ":TestMockStackMetrics",
":TestMockStackSdp",
"fuzzers/rfcomm_fuzzer.cc",
"rfcomm/*.cc",
@@ -465,6 +463,7 @@ cc_fuzz {
":TestMockBtif",
":TestMockDevice",
":TestMockMainShim",
+ ":TestMockMainShim",
":TestMockMainShimEntry",
":TestMockSrvcDis",
":TestMockStackAcl",
@@ -473,7 +472,6 @@ cc_fuzz {
":TestMockStackConnMgr",
":TestMockStackHcic",
":TestMockStackL2cap",
- ":TestMockStackMetrics",
":TestMockStackSdp",
"ais/*.cc",
"eatt/*.cc",
@@ -517,12 +515,12 @@ cc_fuzz {
":TestMockBtif",
":TestMockDevice",
":TestMockMainShim",
+ ":TestMockMainShim",
":TestMockMainShimEntry",
":TestMockStackAcl",
":TestMockStackBtm",
":TestMockStackHcic",
":TestMockStackL2cap",
- ":TestMockStackMetrics",
"fuzzers/smp_fuzzer.cc",
"smp/*.cc", // add other sources files (p256 related) under smp into this test
],
@@ -563,12 +561,12 @@ cc_fuzz {
":TestMockBtif",
":TestMockDevice",
":TestMockMainShim",
+ ":TestMockMainShim",
":TestMockMainShimEntry",
":TestMockStackAcl",
":TestMockStackBtm",
":TestMockStackHcic",
":TestMockStackL2cap",
- ":TestMockStackMetrics",
"bnep/*.cc",
"fuzzers/bnep_fuzzer.cc",
],
@@ -601,12 +599,12 @@ cc_fuzz {
":TestMockBtif",
":TestMockDevice",
":TestMockMainShim",
+ ":TestMockMainShim",
":TestMockMainShimEntry",
":TestMockStackAcl",
":TestMockStackBtm",
":TestMockStackHcic",
":TestMockStackL2cap",
- ":TestMockStackMetrics",
":TestMockStackSdp",
"avct/*.cc",
"avrc/*.cc",
@@ -648,11 +646,11 @@ cc_fuzz {
":TestMockBtif",
":TestMockDevice",
":TestMockMainShim",
+ ":TestMockMainShim",
":TestMockMainShimEntry",
":TestMockStackAcl",
":TestMockStackBtm",
":TestMockStackHcic",
- ":TestMockStackMetrics",
"fuzzers/l2cap_fuzzer.cc",
"l2cap/*.cc",
],
@@ -809,10 +807,10 @@ cc_test {
":TestCommonMockFunctions",
":TestMockHci",
":TestMockMainShim",
+ ":TestMockMainShim",
":TestMockMainShimEntry",
":TestMockStackBtm",
":TestMockStackL2capInterface",
- ":TestMockStackMetrics",
":TestMockStackRfcommMetrics",
"rfcomm/port_api.cc",
"rfcomm/port_rfc.cc",
@@ -903,12 +901,12 @@ cc_test {
":TestMockBtif",
":TestMockDevice",
":TestMockMainShim",
+ ":TestMockMainShim",
":TestMockMainShimEntry",
":TestMockStackAcl",
":TestMockStackBtm",
":TestMockStackHcic",
":TestMockStackL2cap",
- ":TestMockStackMetrics",
"smp/p_256_curvepara.cc",
"smp/p_256_ecc_pp.cc",
"smp/p_256_multprecision.cc",
@@ -1006,9 +1004,9 @@ cc_test {
":TestCommonMainHandler",
":TestCommonMockFunctions",
":TestMockMainShim",
+ ":TestMockMainShim",
":TestMockMainShimEntry",
":TestMockStackBtm",
- ":TestMockStackMetrics",
"connection_manager/connection_manager.cc",
"test/connection_manager_test.cc",
],
@@ -1419,10 +1417,10 @@ cc_test {
":TestMockBtif",
":TestMockDevice",
":TestMockMainShim",
+ ":TestMockMainShim",
":TestMockStackBtm",
":TestMockStackConnMgr",
":TestMockStackL2cap",
- ":TestMockStackMetrics",
"gatt/gatt_db.cc",
"gatt/gatt_sr_hash.cc",
"gatt/gatt_utils.cc",
@@ -1675,7 +1673,6 @@ cc_test {
"btm/hfp_msbc_decoder.cc",
"btm/hfp_msbc_encoder.cc",
"btm/security_event_parser.cc",
- "metrics/stack_metrics_logging.cc",
"test/btm/peer_packet_types_test.cc",
"test/btm/sco_hci_test.cc",
"test/btm/sco_pkt_status_test.cc",
@@ -1813,9 +1810,9 @@ cc_test {
],
srcs: [
":TestCommonMockFunctions",
+ ":TestMockMainShim",
":TestMockStackBtm",
":TestMockStackL2cap",
- ":TestMockStackMetrics",
":TestMockStackSdp",
"hid/hidd_api.cc",
"hid/hidd_conn.cc",
@@ -1887,12 +1884,12 @@ cc_test {
":TestMockBtif",
":TestMockHci",
":TestMockMainShim",
+ ":TestMockMainShim",
":TestMockMainShimEntry",
":TestMockStackAcl",
":TestMockStackBtm",
":TestMockStackHcic",
":TestMockStackL2cap",
- ":TestMockStackMetrics",
":TestMockStackSmp",
"btu/btu_hcif.cc",
"btu/main_thread.cc",
@@ -1964,12 +1961,12 @@ cc_test {
":TestMockBtif",
":TestMockHci",
":TestMockMainShim",
+ ":TestMockMainShim",
":TestMockMainShimEntry",
":TestMockSrvcDis",
":TestMockStackAcl",
":TestMockStackBtm",
":TestMockStackL2cap",
- ":TestMockStackMetrics",
":TestMockStackSdp",
":TestMockStackSmp",
"ais/ais_ble.cc",
@@ -2165,6 +2162,7 @@ cc_test {
":TestMockHci",
":TestMockLegacyHciInterface",
":TestMockMainShim",
+ ":TestMockMainShim",
":TestMockMainShimEntry",
":TestMockStackBtm",
":TestMockStackBtu",
@@ -2172,7 +2170,6 @@ cc_test {
":TestMockStackGatt",
":TestMockStackHcic",
":TestMockStackL2cap",
- ":TestMockStackMetrics",
":TestMockStackSdp",
":TestMockStackSmp",
"acl/*.cc",
@@ -2349,9 +2346,9 @@ cc_test {
":TestFakeOsi",
":TestMockBta",
":TestMockBtif",
+ ":TestMockMainShim",
":TestMockStackBtm",
":TestMockStackL2cap",
- ":TestMockStackMetrics",
"test/sdp/stack_sdp_api_test.cc",
"test/sdp/stack_sdp_db_test.cc",
"test/sdp/stack_sdp_parse_test.cc",
diff --git a/system/stack/BUILD.gn b/system/stack/BUILD.gn
index d078d1bc14..f06a098bd5 100644
--- a/system/stack/BUILD.gn
+++ b/system/stack/BUILD.gn
@@ -149,7 +149,6 @@ source_set("stack") {
"l2cap/l2c_main.cc",
"l2cap/l2c_utils.cc",
"l2cap/l2cap_api.cc",
- "metrics/stack_metrics_logging.cc",
"pan/pan_api.cc",
"pan/pan_main.cc",
"pan/pan_utils.cc",
@@ -210,7 +209,6 @@ source_set("stack") {
"//bt/system/ctrlr/include",
"//bt/system/gd",
"//bt/system/hcis",
- "//bt/system/linux_include",
"//bt/system/rpc/include",
"//bt/system/udrv/include",
"//bt/system/vnd/ble",
@@ -367,7 +365,6 @@ if (defined(use.android) && use.android) {
include_dirs = [
"//bt/system/",
- "//bt/system/linux_include",
"//bt/system/bta/include",
"//bt/system/bta/sys",
"//bt/system/embdrv/sbc/encoder/include",
diff --git a/system/stack/btm/btm_ble_sec.cc b/system/stack/btm/btm_ble_sec.cc
index 05d1c16337..cef553c79e 100644
--- a/system/stack/btm/btm_ble_sec.cc
+++ b/system/stack/btm/btm_ble_sec.cc
@@ -744,16 +744,28 @@ tBTM_STATUS btm_ble_start_sec_check(const RawAddress& bd_addr, uint16_t psm, boo
bool is_encrypted = BTM_IsEncrypted(bd_addr, BT_TRANSPORT_LE);
bool is_link_key_authed = BTM_IsLinkKeyAuthed(bd_addr, BT_TRANSPORT_LE);
bool is_authenticated = BTM_IsAuthenticated(bd_addr, BT_TRANSPORT_LE);
+ bool is_bonded = BTM_IsBonded(bd_addr, BT_TRANSPORT_LE);
if (!is_originator) {
- if ((p_serv_rec->security_flags & BTM_SEC_IN_ENCRYPT) && !is_encrypted) {
- log::error("BTM_NOT_ENCRYPTED. service security_flags=0x{:x}", p_serv_rec->security_flags);
- return tBTM_STATUS::BTM_NOT_ENCRYPTED;
- } else if ((p_serv_rec->security_flags & BTM_SEC_IN_AUTHENTICATE) &&
- !(is_link_key_authed || is_authenticated)) {
- log::error("tBTM_STATUS::BTM_NOT_AUTHENTICATED. service security_flags=0x{:x}",
- p_serv_rec->security_flags);
- return tBTM_STATUS::BTM_NOT_AUTHENTICATED;
+ if (!com::android::bluetooth::flags::donot_mandate_auth_along_with_encryption()) {
+ if ((p_serv_rec->security_flags & BTM_SEC_IN_ENCRYPT) && !is_encrypted) {
+ log::error("BTM_NOT_ENCRYPTED. service security_flags=0x{:x}", p_serv_rec->security_flags);
+ return tBTM_STATUS::BTM_NOT_ENCRYPTED;
+ } else if ((p_serv_rec->security_flags & BTM_SEC_IN_AUTHENTICATE) &&
+ !(is_link_key_authed || is_authenticated)) {
+ log::error("tBTM_STATUS::BTM_NOT_AUTHENTICATED. service security_flags=0x{:x}",
+ p_serv_rec->security_flags);
+ return tBTM_STATUS::BTM_NOT_AUTHENTICATED;
+ }
+ } else {
+ if ((p_serv_rec->security_flags & BTM_SEC_IN_ENCRYPT) && !is_encrypted) {
+ log::error("BTM_NOT_ENCRYPTED. service security_flags=0x{:x}", p_serv_rec->security_flags);
+ return tBTM_STATUS::BTM_NOT_ENCRYPTED;
+ } else if ((p_serv_rec->security_flags & BTM_SEC_IN_AUTHENTICATE) && !(is_bonded)) {
+ log::error("tBTM_STATUS::BTM_NOT_AUTHENTICATED. service security_flags=0x{:x}",
+ p_serv_rec->security_flags);
+ return tBTM_STATUS::BTM_NOT_AUTHENTICATED;
+ }
}
/* TODO: When security is required, then must check that the key size of our
service is equal or smaller than the incoming connection key size. */
@@ -1609,8 +1621,16 @@ void btm_ble_connection_established(const RawAddress& bda) {
!p_dev_rec->sec_rec.is_le_link_key_known())) {
// Unknown device
if (p_dev_rec->dev_class == kDevClassEmpty || p_dev_rec->dev_class == kDevClassUnclassified) {
- // Class of device not known, read appearance characteristic
- btm_ble_read_remote_cod(bda);
+ // Class of device not known, read appearance characteristic ...
+ // Unless it is one of those devices which don't respond to this request
+ BD_NAME remote_name = {};
+ if (p_dev_rec->sec_rec.is_name_known() && BTM_GetRemoteDeviceName(bda, remote_name) &&
+ interop_match_name(INTEROP_DISABLE_READ_LE_APPEARANCE, (const char*)remote_name)) {
+ log::warn("Name {} matches IOP database, not reading appearance for {}",
+ (const char*)remote_name, bda);
+ } else {
+ btm_ble_read_remote_cod(bda);
+ }
}
}
}
@@ -1677,7 +1697,6 @@ static void btm_ble_consent_req(const RawAddress& bd_addr, tBTM_LE_EVT_DATA* p_d
static void btm_ble_complete_evt(const RawAddress& bd_addr, tBTM_SEC_DEV_REC* p_dev_rec,
tBTM_LE_EVT_DATA* p_data) {
-
if (btm_ble_complete_evt_ignore(p_dev_rec, p_data)) {
return;
}
diff --git a/system/stack/btm/btm_sco.cc b/system/stack/btm/btm_sco.cc
index c48b321448..82182135eb 100644
--- a/system/stack/btm/btm_sco.cc
+++ b/system/stack/btm/btm_sco.cc
@@ -44,6 +44,7 @@
#include "internal_include/bt_target.h"
#include "main/shim/entry.h"
#include "main/shim/helpers.h"
+#include "main/shim/metrics_api.h"
#include "osi/include/properties.h"
#include "osi/include/stack_power_telemetry.h"
#include "stack/btm/btm_int_types.h"
@@ -60,7 +61,6 @@
#include "stack/include/main_thread.h"
#include "stack/include/sco_hci_link_interface.h"
#include "stack/include/sdpdefs.h"
-#include "stack/include/stack_metrics_logging.h"
#include "types/raw_address.h"
extern tBTM_CB btm_cb;
@@ -1298,7 +1298,8 @@ static void btm_sco_on_disconnected(uint16_t hci_handle, tHCI_REASON reason) {
if (fill_plc_stats(&num_decoded_frames, &packet_loss_ratio)) {
const int16_t codec_id = sco_codec_type_to_id(codec_type);
const std::string codec = sco_codec_type_text(codec_type);
- log_hfp_audio_packet_loss_stats(bd_addr, num_decoded_frames, packet_loss_ratio, codec_id);
+ bluetooth::shim::LogMetricHfpPacketLossStats(bd_addr, num_decoded_frames, packet_loss_ratio,
+ codec_id);
log::debug(
"Stopped SCO codec:{}, num_decoded_frames:{}, "
"packet_loss_ratio:{:f}",
diff --git a/system/stack/btm/btm_sec.cc b/system/stack/btm/btm_sec.cc
index b00b779eee..6244b951c6 100644
--- a/system/stack/btm/btm_sec.cc
+++ b/system/stack/btm/btm_sec.cc
@@ -47,6 +47,7 @@
#include "main/shim/acl_api.h"
#include "main/shim/entry.h"
#include "main/shim/helpers.h"
+#include "main/shim/metrics_api.h"
#include "metrics/bluetooth_event.h"
#include "osi/include/allocator.h"
#include "osi/include/properties.h"
@@ -75,7 +76,6 @@
#include "stack/include/main_thread.h"
#include "stack/include/rnr_interface.h"
#include "stack/include/smp_api.h"
-#include "stack/include/stack_metrics_logging.h"
#include "types/bt_transport.h"
#include "types/raw_address.h"
@@ -1923,7 +1923,7 @@ static void btm_sec_bond_cancel_complete(void) {
void btm_create_conn_cancel_complete(uint8_t status, const RawAddress bd_addr) {
log::verbose("btm_create_conn_cancel_complete(): in State: {} status:{}",
tBTM_SEC_CB::btm_pair_state_descr(btm_sec_cb.pairing_state), status);
- log_link_layer_connection_event(
+ bluetooth::shim::LogMetricLinkLayerConnectionEvent(
&bd_addr, bluetooth::common::kUnknownConnectionHandle,
android::bluetooth::DIRECTION_OUTGOING, android::bluetooth::LINK_TYPE_ACL,
android::bluetooth::hci::CMD_CREATE_CONNECTION_CANCEL,
@@ -2440,8 +2440,7 @@ void btm_io_capabilities_req(RawAddress p) {
/* If device is bonded, and encrypted it's upgrading security and it's ok.
* If it's bonded and not encrypted, it's remote missing keys scenario */
- if (!p_dev_rec->sec_rec.is_device_encrypted() &&
- com::android::bluetooth::flags::key_missing_classic_device()) {
+ if (!p_dev_rec->sec_rec.is_device_encrypted()) {
log::warn("Incoming bond request, but {} is already bonded (notifying user)", p);
bta_dm_remote_key_missing(p);
btm_sec_disconnect(p_dev_rec->hci_handle, HCI_ERR_AUTH_FAILURE,
@@ -2632,8 +2631,7 @@ void btm_io_capabilities_rsp(const tBTM_SP_IO_RSP evt_data) {
/* If device is bonded, and encrypted it's upgrading security and it's ok.
* If it's bonded and not encrypted, it's remote missing keys scenario */
- if (btm_sec_is_a_bonded_dev(evt_data.bd_addr) && !p_dev_rec->sec_rec.is_device_encrypted() &&
- com::android::bluetooth::flags::key_missing_classic_device()) {
+ if (btm_sec_is_a_bonded_dev(evt_data.bd_addr) && !p_dev_rec->sec_rec.is_device_encrypted()) {
log::warn("Incoming bond request, but {} is already bonded (notifying user)", evt_data.bd_addr);
bta_dm_remote_key_missing(evt_data.bd_addr);
btm_sec_disconnect(p_dev_rec->hci_handle, HCI_ERR_AUTH_FAILURE,
@@ -3031,8 +3029,7 @@ void btm_sec_auth_complete(uint16_t handle, tHCI_STATUS status) {
p_dev_rec->sec_rec.classic_link, p_dev_rec->bd_addr,
reinterpret_cast<char const*>(p_dev_rec->sec_bd_name));
- if (status == HCI_ERR_KEY_MISSING &&
- com::android::bluetooth::flags::key_missing_classic_device()) {
+ if (status == HCI_ERR_KEY_MISSING) {
log::warn("auth_complete KEY_MISSING {} is already bonded (notifying user)",
p_dev_rec->bd_addr);
bta_dm_remote_key_missing(p_dev_rec->bd_addr);
@@ -3133,12 +3130,12 @@ void btm_sec_auth_complete(uint16_t handle, tHCI_STATUS status) {
p_dev_rec->sec_rec.security_required &= ~BTM_SEC_OUT_AUTHENTICATE;
if (status != HCI_SUCCESS) {
- if ((status != HCI_ERR_PEER_USER) && (status != HCI_ERR_CONN_CAUSE_LOCAL_HOST)) {
+ if (status != HCI_ERR_PEER_USER && status != HCI_ERR_CONN_CAUSE_LOCAL_HOST) {
btm_sec_send_hci_disconnect(
p_dev_rec, HCI_ERR_PEER_USER, p_dev_rec->hci_handle,
"stack::btm::btm_sec::btm_sec_auth_retry Auth fail while bonding");
}
- } else {
+ } else if (!com::android::bluetooth::flags::immediate_encryption_after_pairing()) {
BTM_LogHistory(kBtmLogTag, p_dev_rec->bd_addr, "Bonding completed",
hci_error_code_text(status));
@@ -3163,6 +3160,11 @@ void btm_sec_auth_complete(uint16_t handle, tHCI_STATUS status) {
}
l2cu_start_post_bond_timer(p_dev_rec->hci_handle);
+ } else {
+ BTM_LogHistory(kBtmLogTag, p_dev_rec->bd_addr, "Bonding completed",
+ hci_error_code_text(status));
+ BTM_SetEncryption(p_dev_rec->bd_addr, BT_TRANSPORT_BR_EDR, NULL, NULL, BTM_BLE_SEC_NONE);
+ l2cu_start_post_bond_timer(p_dev_rec->hci_handle);
}
return;
@@ -3321,10 +3323,8 @@ void btm_sec_encrypt_change(uint16_t handle, tHCI_STATUS status, uint8_t encr_en
if (status == HCI_ERR_KEY_MISSING) {
log::info("Remote key missing - will report");
bta_dm_remote_key_missing(p_dev_rec->ble.pseudo_addr);
- if (com::android::bluetooth::flags::sec_disconnect_on_le_key_missing()) {
- btm_sec_send_hci_disconnect(p_dev_rec, HCI_ERR_HOST_REJECT_SECURITY,
- p_dev_rec->ble_hci_handle, "encryption_change:key_missing");
- }
+ btm_sec_send_hci_disconnect(p_dev_rec, HCI_ERR_HOST_REJECT_SECURITY,
+ p_dev_rec->ble_hci_handle, "encryption_change:key_missing");
return;
}
diff --git a/system/stack/btm/security_event_parser.cc b/system/stack/btm/security_event_parser.cc
index 84d7005d16..deba84b67f 100644
--- a/system/stack/btm/security_event_parser.cc
+++ b/system/stack/btm/security_event_parser.cc
@@ -25,10 +25,10 @@
#include "common/metrics.h"
#include "hci/hci_packets.h"
#include "main/shim/helpers.h"
+#include "main/shim/metrics_api.h"
#include "stack/include/btm_sec_api_types.h"
#include "stack/include/hci_error_code.h"
#include "stack/include/sec_hci_link_interface.h"
-#include "stack/include/stack_metrics_logging.h"
#include "types/raw_address.h"
using namespace bluetooth;
@@ -46,8 +46,8 @@ static void log_address_and_status(const Address& bda, EventCode event_code,
uint16_t reason = android::bluetooth::hci::STATUS_UNKNOWN;
uint16_t handle = bluetooth::common::kUnknownConnectionHandle;
int64_t value = 0;
- log_classic_pairing_event(ToRawAddress(bda), handle, cmd, static_cast<uint16_t>(event_code),
- status, reason, value);
+ bluetooth::shim::LogMetricClassicPairingEvent(
+ ToRawAddress(bda), handle, cmd, static_cast<uint16_t>(event_code), status, reason, value);
}
static void log_address(const Address& bda, EventCode event_code) {
uint32_t cmd = android::bluetooth::hci::CMD_UNKNOWN;
@@ -55,8 +55,8 @@ static void log_address(const Address& bda, EventCode event_code) {
uint16_t reason = android::bluetooth::hci::STATUS_UNKNOWN;
uint16_t handle = bluetooth::common::kUnknownConnectionHandle;
int64_t value = 0;
- log_classic_pairing_event(ToRawAddress(bda), handle, cmd, static_cast<uint16_t>(event_code),
- status, reason, value);
+ bluetooth::shim::LogMetricClassicPairingEvent(
+ ToRawAddress(bda), handle, cmd, static_cast<uint16_t>(event_code), status, reason, value);
}
static void parse_encryption_change(const EventView event) {
auto change_opt = EncryptionChangeView::CreateOptional(event);
@@ -69,7 +69,7 @@ static void parse_encryption_change(const EventView event) {
btm_sec_encryption_change_evt(handle, static_cast<tHCI_STATUS>(status),
static_cast<uint8_t>(encr_enable), 0);
- log_classic_pairing_event(
+ bluetooth::shim::LogMetricClassicPairingEvent(
ToRawAddress(Address::kEmpty), handle, android::bluetooth::hci::CMD_UNKNOWN,
static_cast<uint32_t>(change.GetEventCode()), static_cast<uint16_t>(status),
android::bluetooth::hci::STATUS_UNKNOWN, 0);
@@ -86,7 +86,7 @@ static void parse_encryption_change_v2(const EventView event) {
btm_sec_encryption_change_evt(handle, static_cast<tHCI_STATUS>(status),
static_cast<uint8_t>(encr_enable), key_size);
- log_classic_pairing_event(
+ bluetooth::shim::LogMetricClassicPairingEvent(
ToRawAddress(Address::kEmpty), handle, android::bluetooth::hci::CMD_UNKNOWN,
static_cast<uint32_t>(change.GetEventCode()), static_cast<uint16_t>(status),
android::bluetooth::hci::STATUS_UNKNOWN, 0);
@@ -96,7 +96,7 @@ static void parse_change_connection_link_key_complete(const EventView event) {
log::assert_that(complete_opt.has_value(), "assert failed: complete_opt.has_value()");
auto complete = complete_opt.value();
- log_classic_pairing_event(
+ bluetooth::shim::LogMetricClassicPairingEvent(
ToRawAddress(Address::kEmpty), complete.GetConnectionHandle(),
android::bluetooth::hci::CMD_UNKNOWN, static_cast<uint32_t>(complete.GetEventCode()),
static_cast<uint16_t>(complete.GetStatus()), android::bluetooth::hci::STATUS_UNKNOWN, 0);
diff --git a/system/stack/btu/btu_hcif.cc b/system/stack/btu/btu_hcif.cc
index 7a4b6d1256..ee3c9757a5 100644
--- a/system/stack/btu/btu_hcif.cc
+++ b/system/stack/btu/btu_hcif.cc
@@ -40,6 +40,7 @@
#include "common/metrics.h"
#include "internal_include/bt_target.h"
#include "main/shim/hci_layer.h"
+#include "main/shim/metrics_api.h"
#include "osi/include/allocator.h"
#include "stack/include/acl_api.h"
#include "stack/include/acl_hci_link_interface.h"
@@ -59,7 +60,6 @@
#include "stack/include/sco_hci_link_interface.h"
#include "stack/include/sec_hci_link_interface.h"
#include "stack/include/smp_api.h"
-#include "stack/include/stack_metrics_logging.h"
#include "types/hci_role.h"
#include "types/raw_address.h"
@@ -125,25 +125,29 @@ static void btu_hcif_log_event_metrics(uint8_t evt_code, const uint8_t* p_event)
case HCI_KEYPRESS_NOTIFY_EVT:
case HCI_REMOTE_OOB_DATA_REQUEST_EVT:
STREAM_TO_BDADDR(bda, p_event);
- log_classic_pairing_event(bda, handle, cmd, evt_code, status, reason, value);
+ bluetooth::shim::LogMetricClassicPairingEvent(bda, handle, cmd, evt_code, status, reason,
+ value);
break;
case HCI_SIMPLE_PAIRING_COMPLETE_EVT:
STREAM_TO_UINT8(status, p_event);
STREAM_TO_BDADDR(bda, p_event);
- log_classic_pairing_event(bda, handle, cmd, evt_code, status, reason, value);
+ bluetooth::shim::LogMetricClassicPairingEvent(bda, handle, cmd, evt_code, status, reason,
+ value);
break;
case HCI_AUTHENTICATION_COMP_EVT:
STREAM_TO_UINT8(status, p_event);
STREAM_TO_UINT16(handle, p_event);
handle = HCID_GET_HANDLE(handle);
- log_classic_pairing_event(bda, handle, cmd, evt_code, status, reason, value);
+ bluetooth::shim::LogMetricClassicPairingEvent(bda, handle, cmd, evt_code, status, reason,
+ value);
break;
case HCI_ENCRYPTION_CHANGE_EVT: {
uint8_t encryption_enabled;
STREAM_TO_UINT8(status, p_event);
STREAM_TO_UINT16(handle, p_event);
STREAM_TO_UINT8(encryption_enabled, p_event);
- log_classic_pairing_event(bda, handle, cmd, evt_code, status, reason, encryption_enabled);
+ bluetooth::shim::LogMetricClassicPairingEvent(bda, handle, cmd, evt_code, status, reason,
+ encryption_enabled);
break;
}
case HCI_ENCRYPTION_CHANGE_EVT_V2: {
@@ -153,7 +157,8 @@ static void btu_hcif_log_event_metrics(uint8_t evt_code, const uint8_t* p_event)
STREAM_TO_UINT16(handle, p_event);
STREAM_TO_UINT8(encryption_enabled, p_event);
STREAM_TO_UINT8(key_size, p_event);
- log_classic_pairing_event(bda, handle, cmd, evt_code, status, reason, encryption_enabled);
+ bluetooth::shim::LogMetricClassicPairingEvent(bda, handle, cmd, evt_code, status, reason,
+ encryption_enabled);
break;
}
case HCI_ESCO_CONNECTION_COMP_EVT: {
@@ -163,18 +168,19 @@ static void btu_hcif_log_event_metrics(uint8_t evt_code, const uint8_t* p_event)
STREAM_TO_BDADDR(bda, p_event);
STREAM_TO_UINT8(link_type, p_event);
handle = HCID_GET_HANDLE(handle);
- log_link_layer_connection_event(&bda, handle, android::bluetooth::DIRECTION_UNKNOWN,
- link_type, cmd, evt_code,
- android::bluetooth::hci::BLE_EVT_UNKNOWN, status, reason);
+ bluetooth::shim::LogMetricLinkLayerConnectionEvent(
+ &bda, handle, android::bluetooth::DIRECTION_UNKNOWN, link_type, cmd, evt_code,
+ android::bluetooth::hci::BLE_EVT_UNKNOWN, status, reason);
break;
}
case HCI_ESCO_CONNECTION_CHANGED_EVT: {
STREAM_TO_UINT8(status, p_event);
STREAM_TO_UINT16(handle, p_event);
handle = HCID_GET_HANDLE(handle);
- log_link_layer_connection_event(nullptr, handle, android::bluetooth::DIRECTION_UNKNOWN,
- android::bluetooth::LINK_TYPE_UNKNOWN, cmd, evt_code,
- android::bluetooth::hci::BLE_EVT_UNKNOWN, status, reason);
+ bluetooth::shim::LogMetricLinkLayerConnectionEvent(
+ nullptr, handle, android::bluetooth::DIRECTION_UNKNOWN,
+ android::bluetooth::LINK_TYPE_UNKNOWN, cmd, evt_code,
+ android::bluetooth::hci::BLE_EVT_UNKNOWN, status, reason);
break;
}
// Ignore these events
@@ -368,7 +374,7 @@ static void btu_hcif_log_command_metrics(uint16_t opcode, const uint8_t* p_cmd,
case HCI_CREATE_CONNECTION:
case HCI_CREATE_CONNECTION_CANCEL:
STREAM_TO_BDADDR(bd_addr, p_cmd);
- log_link_layer_connection_event(
+ bluetooth::shim::LogMetricLinkLayerConnectionEvent(
&bd_addr, bluetooth::common::kUnknownConnectionHandle,
android::bluetooth::DIRECTION_OUTGOING, android::bluetooth::LINK_TYPE_ACL, opcode,
hci_event, kUnknownBleEvt, cmd_status, android::bluetooth::hci::STATUS_UNKNOWN);
@@ -376,23 +382,24 @@ static void btu_hcif_log_command_metrics(uint16_t opcode, const uint8_t* p_cmd,
case HCI_DISCONNECT:
STREAM_TO_UINT16(handle, p_cmd);
STREAM_TO_UINT8(reason, p_cmd);
- log_link_layer_connection_event(nullptr, handle, android::bluetooth::DIRECTION_UNKNOWN,
- android::bluetooth::LINK_TYPE_UNKNOWN, opcode, hci_event,
- kUnknownBleEvt, cmd_status, reason);
+ bluetooth::shim::LogMetricLinkLayerConnectionEvent(
+ nullptr, handle, android::bluetooth::DIRECTION_UNKNOWN,
+ android::bluetooth::LINK_TYPE_UNKNOWN, opcode, hci_event, kUnknownBleEvt, cmd_status,
+ reason);
break;
case HCI_SETUP_ESCO_CONNECTION:
case HCI_ENH_SETUP_ESCO_CONNECTION:
STREAM_TO_UINT16(handle, p_cmd);
- log_link_layer_connection_event(nullptr, handle, android::bluetooth::DIRECTION_OUTGOING,
- android::bluetooth::LINK_TYPE_UNKNOWN, opcode, hci_event,
- kUnknownBleEvt, cmd_status,
- android::bluetooth::hci::STATUS_UNKNOWN);
+ bluetooth::shim::LogMetricLinkLayerConnectionEvent(
+ nullptr, handle, android::bluetooth::DIRECTION_OUTGOING,
+ android::bluetooth::LINK_TYPE_UNKNOWN, opcode, hci_event, kUnknownBleEvt, cmd_status,
+ android::bluetooth::hci::STATUS_UNKNOWN);
break;
case HCI_ACCEPT_CONNECTION_REQUEST:
case HCI_ACCEPT_ESCO_CONNECTION:
case HCI_ENH_ACCEPT_ESCO_CONNECTION:
STREAM_TO_BDADDR(bd_addr, p_cmd);
- log_link_layer_connection_event(
+ bluetooth::shim::LogMetricLinkLayerConnectionEvent(
&bd_addr, bluetooth::common::kUnknownConnectionHandle,
android::bluetooth::DIRECTION_INCOMING, android::bluetooth::LINK_TYPE_UNKNOWN, opcode,
hci_event, kUnknownBleEvt, cmd_status, android::bluetooth::hci::STATUS_UNKNOWN);
@@ -401,10 +408,10 @@ static void btu_hcif_log_command_metrics(uint16_t opcode, const uint8_t* p_cmd,
case HCI_REJECT_ESCO_CONNECTION:
STREAM_TO_BDADDR(bd_addr, p_cmd);
STREAM_TO_UINT8(reason, p_cmd);
- log_link_layer_connection_event(&bd_addr, bluetooth::common::kUnknownConnectionHandle,
- android::bluetooth::DIRECTION_INCOMING,
- android::bluetooth::LINK_TYPE_UNKNOWN, opcode, hci_event,
- kUnknownBleEvt, cmd_status, reason);
+ bluetooth::shim::LogMetricLinkLayerConnectionEvent(
+ &bd_addr, bluetooth::common::kUnknownConnectionHandle,
+ android::bluetooth::DIRECTION_INCOMING, android::bluetooth::LINK_TYPE_UNKNOWN, opcode,
+ hci_event, kUnknownBleEvt, cmd_status, reason);
break;
// BLE Commands
@@ -431,7 +438,7 @@ static void btu_hcif_log_command_metrics(uint16_t opcode, const uint8_t* p_cmd,
// Selectively log to avoid log spam due to acceptlist connections:
// - When doing non-acceptlist connection
// - When there is an error in command status
- log_link_layer_connection_event(
+ bluetooth::shim::LogMetricLinkLayerConnectionEvent(
bd_addr_p, bluetooth::common::kUnknownConnectionHandle,
android::bluetooth::DIRECTION_OUTGOING, android::bluetooth::LINK_TYPE_ACL, opcode,
hci_event, kUnknownBleEvt, cmd_status, android::bluetooth::hci::STATUS_UNKNOWN);
@@ -456,7 +463,7 @@ static void btu_hcif_log_command_metrics(uint16_t opcode, const uint8_t* p_cmd,
// Selectively log to avoid log spam due to acceptlist connections:
// - When doing non-acceptlist connection
// - When there is an error in command status
- log_link_layer_connection_event(
+ bluetooth::shim::LogMetricLinkLayerConnectionEvent(
bd_addr_p, bluetooth::common::kUnknownConnectionHandle,
android::bluetooth::DIRECTION_OUTGOING, android::bluetooth::LINK_TYPE_ACL, opcode,
hci_event, kUnknownBleEvt, cmd_status, android::bluetooth::hci::STATUS_UNKNOWN);
@@ -466,7 +473,7 @@ static void btu_hcif_log_command_metrics(uint16_t opcode, const uint8_t* p_cmd,
case HCI_BLE_CREATE_CONN_CANCEL:
if (cmd_status != HCI_SUCCESS && !is_cmd_status) {
// Only log errors to prevent log spam due to acceptlist connections
- log_link_layer_connection_event(
+ bluetooth::shim::LogMetricLinkLayerConnectionEvent(
nullptr, bluetooth::common::kUnknownConnectionHandle,
android::bluetooth::DIRECTION_OUTGOING, android::bluetooth::LINK_TYPE_ACL, opcode,
hci_event, kUnknownBleEvt, cmd_status, android::bluetooth::hci::STATUS_UNKNOWN);
@@ -474,46 +481,48 @@ static void btu_hcif_log_command_metrics(uint16_t opcode, const uint8_t* p_cmd,
break;
case HCI_READ_LOCAL_OOB_DATA:
case HCI_READ_LOCAL_OOB_EXTENDED_DATA:
- log_classic_pairing_event(RawAddress::kEmpty, bluetooth::common::kUnknownConnectionHandle,
- opcode, hci_event, cmd_status,
- android::bluetooth::hci::STATUS_UNKNOWN, 0);
+ bluetooth::shim::LogMetricClassicPairingEvent(
+ RawAddress::kEmpty, bluetooth::common::kUnknownConnectionHandle, opcode, hci_event,
+ cmd_status, android::bluetooth::hci::STATUS_UNKNOWN, 0);
break;
case HCI_WRITE_SIMPLE_PAIRING_MODE: {
uint8_t simple_pairing_mode;
STREAM_TO_UINT8(simple_pairing_mode, p_cmd);
- log_classic_pairing_event(RawAddress::kEmpty, bluetooth::common::kUnknownConnectionHandle,
- opcode, hci_event, cmd_status,
- android::bluetooth::hci::STATUS_UNKNOWN, simple_pairing_mode);
+ bluetooth::shim::LogMetricClassicPairingEvent(
+ RawAddress::kEmpty, bluetooth::common::kUnknownConnectionHandle, opcode, hci_event,
+ cmd_status, android::bluetooth::hci::STATUS_UNKNOWN, simple_pairing_mode);
break;
}
case HCI_WRITE_SECURE_CONNS_SUPPORT: {
uint8_t secure_conn_host_support;
STREAM_TO_UINT8(secure_conn_host_support, p_cmd);
- log_classic_pairing_event(RawAddress::kEmpty, bluetooth::common::kUnknownConnectionHandle,
- opcode, hci_event, cmd_status,
- android::bluetooth::hci::STATUS_UNKNOWN, secure_conn_host_support);
+ bluetooth::shim::LogMetricClassicPairingEvent(
+ RawAddress::kEmpty, bluetooth::common::kUnknownConnectionHandle, opcode, hci_event,
+ cmd_status, android::bluetooth::hci::STATUS_UNKNOWN, secure_conn_host_support);
break;
}
case HCI_AUTHENTICATION_REQUESTED:
STREAM_TO_UINT16(handle, p_cmd);
- log_classic_pairing_event(RawAddress::kEmpty, handle, opcode, hci_event, cmd_status,
- android::bluetooth::hci::STATUS_UNKNOWN, 0);
+ bluetooth::shim::LogMetricClassicPairingEvent(RawAddress::kEmpty, handle, opcode, hci_event,
+ cmd_status,
+ android::bluetooth::hci::STATUS_UNKNOWN, 0);
break;
case HCI_SET_CONN_ENCRYPTION: {
STREAM_TO_UINT16(handle, p_cmd);
uint8_t encryption_enable;
STREAM_TO_UINT8(encryption_enable, p_cmd);
- log_classic_pairing_event(RawAddress::kEmpty, handle, opcode, hci_event, cmd_status,
- android::bluetooth::hci::STATUS_UNKNOWN, encryption_enable);
+ bluetooth::shim::LogMetricClassicPairingEvent(
+ RawAddress::kEmpty, handle, opcode, hci_event, cmd_status,
+ android::bluetooth::hci::STATUS_UNKNOWN, encryption_enable);
break;
}
case HCI_DELETE_STORED_LINK_KEY: {
uint8_t delete_all_flag;
STREAM_TO_BDADDR(bd_addr, p_cmd);
STREAM_TO_UINT8(delete_all_flag, p_cmd);
- log_classic_pairing_event(bd_addr, bluetooth::common::kUnknownConnectionHandle, opcode,
- hci_event, cmd_status, android::bluetooth::hci::STATUS_UNKNOWN,
- delete_all_flag);
+ bluetooth::shim::LogMetricClassicPairingEvent(
+ bd_addr, bluetooth::common::kUnknownConnectionHandle, opcode, hci_event, cmd_status,
+ android::bluetooth::hci::STATUS_UNKNOWN, delete_all_flag);
break;
}
case HCI_RMT_NAME_REQUEST:
@@ -528,14 +537,16 @@ static void btu_hcif_log_command_metrics(uint16_t opcode, const uint8_t* p_cmd,
case HCI_REM_OOB_DATA_REQ_REPLY:
case HCI_REM_OOB_DATA_REQ_NEG_REPLY:
STREAM_TO_BDADDR(bd_addr, p_cmd);
- log_classic_pairing_event(bd_addr, bluetooth::common::kUnknownConnectionHandle, opcode,
- hci_event, cmd_status, android::bluetooth::hci::STATUS_UNKNOWN, 0);
+ bluetooth::shim::LogMetricClassicPairingEvent(
+ bd_addr, bluetooth::common::kUnknownConnectionHandle, opcode, hci_event, cmd_status,
+ android::bluetooth::hci::STATUS_UNKNOWN, 0);
break;
case HCI_IO_CAP_REQ_NEG_REPLY:
STREAM_TO_BDADDR(bd_addr, p_cmd);
STREAM_TO_UINT8(reason, p_cmd);
- log_classic_pairing_event(bd_addr, bluetooth::common::kUnknownConnectionHandle, opcode,
- hci_event, cmd_status, reason, 0);
+ bluetooth::shim::LogMetricClassicPairingEvent(bd_addr,
+ bluetooth::common::kUnknownConnectionHandle,
+ opcode, hci_event, cmd_status, reason, 0);
break;
}
}
@@ -599,8 +610,9 @@ static void btu_hcif_log_command_complete_metrics(uint16_t opcode, const uint8_t
case HCI_WRITE_SIMPLE_PAIRING_MODE:
case HCI_WRITE_SECURE_CONNS_SUPPORT:
STREAM_TO_UINT8(status, p_return_params);
- log_classic_pairing_event(RawAddress::kEmpty, bluetooth::common::kUnknownConnectionHandle,
- opcode, hci_event, status, reason, 0);
+ bluetooth::shim::LogMetricClassicPairingEvent(RawAddress::kEmpty,
+ bluetooth::common::kUnknownConnectionHandle,
+ opcode, hci_event, status, reason, 0);
break;
case HCI_READ_ENCR_KEY_SIZE: {
uint16_t handle;
@@ -608,8 +620,8 @@ static void btu_hcif_log_command_complete_metrics(uint16_t opcode, const uint8_t
STREAM_TO_UINT8(status, p_return_params);
STREAM_TO_UINT16(handle, p_return_params);
STREAM_TO_UINT8(key_size, p_return_params);
- log_classic_pairing_event(RawAddress::kEmpty, handle, opcode, hci_event, status, reason,
- key_size);
+ bluetooth::shim::LogMetricClassicPairingEvent(RawAddress::kEmpty, handle, opcode, hci_event,
+ status, reason, key_size);
break;
}
case HCI_LINK_KEY_REQUEST_REPLY:
@@ -624,8 +636,9 @@ static void btu_hcif_log_command_complete_metrics(uint16_t opcode, const uint8_t
case HCI_REM_OOB_DATA_REQ_NEG_REPLY:
STREAM_TO_UINT8(status, p_return_params);
STREAM_TO_BDADDR(bd_addr, p_return_params);
- log_classic_pairing_event(bd_addr, bluetooth::common::kUnknownConnectionHandle, opcode,
- hci_event, status, reason, 0);
+ bluetooth::shim::LogMetricClassicPairingEvent(bd_addr,
+ bluetooth::common::kUnknownConnectionHandle,
+ opcode, hci_event, status, reason, 0);
break;
}
}
diff --git a/system/stack/fuzzers/l2cap_fuzzer.cc b/system/stack/fuzzers/l2cap_fuzzer.cc
index 6cb4d5170f..69243a67c4 100644
--- a/system/stack/fuzzers/l2cap_fuzzer.cc
+++ b/system/stack/fuzzers/l2cap_fuzzer.cc
@@ -121,26 +121,30 @@ public:
GetInterfaceToProfiles()->profileSpecific_HACK->GetHearingAidDeviceCount = []() { return 1; };
- ON_CALL(controller_, GetLeSuggestedDefaultDataLength).WillByDefault(Return(512));
+ bluetooth::hci::testing::mock_controller_ =
+ std::make_unique<bluetooth::hci::testing::MockControllerInterface>();
+ ON_CALL(*bluetooth::hci::testing::mock_controller_, GetLeSuggestedDefaultDataLength)
+ .WillByDefault(Return(512));
bluetooth::hci::LeBufferSize iso_size;
iso_size.le_data_packet_length_ = 512;
iso_size.total_num_le_packets_ = 6;
- ON_CALL(controller_, GetControllerIsoBufferSize).WillByDefault(Return(iso_size));
+ ON_CALL(*bluetooth::hci::testing::mock_controller_, GetControllerIsoBufferSize)
+ .WillByDefault(Return(iso_size));
bluetooth::hci::LeBufferSize le_size;
le_size.le_data_packet_length_ = 512;
le_size.total_num_le_packets_ = 6;
- ON_CALL(controller_, GetLeBufferSize).WillByDefault(Return(le_size));
- ON_CALL(controller_, SupportsBle).WillByDefault(Return(true));
- ON_CALL(controller_, GetAclPacketLength).WillByDefault(Return(512));
- bluetooth::hci::testing::mock_controller_ = &controller_;
+ ON_CALL(*bluetooth::hci::testing::mock_controller_, GetLeBufferSize)
+ .WillByDefault(Return(le_size));
+ ON_CALL(*bluetooth::hci::testing::mock_controller_, SupportsBle).WillByDefault(Return(true));
+ ON_CALL(*bluetooth::hci::testing::mock_controller_, GetAclPacketLength)
+ .WillByDefault(Return(512));
}
~FakeBtStack() {
test::mock::stack_acl::acl_send_data_packet_br_edr = {};
test::mock::stack_acl::acl_send_data_packet_ble = {};
- bluetooth::hci::testing::mock_controller_ = nullptr;
+ bluetooth::hci::testing::mock_controller_.reset();
}
- bluetooth::hci::testing::MockControllerInterface controller_;
};
class Fakes {
diff --git a/system/stack/gatt/gatt_api.cc b/system/stack/gatt/gatt_api.cc
index 1b60132b00..7b1a425f5e 100644
--- a/system/stack/gatt/gatt_api.cc
+++ b/system/stack/gatt/gatt_api.cc
@@ -34,6 +34,7 @@
#include "internal_include/bt_target.h"
#include "internal_include/stack_config.h"
#include "main/shim/helpers.h"
+#include "main/shim/metrics_api.h"
#include "os/system_properties.h"
#include "osi/include/allocator.h"
#include "stack/arbiter/acl_arbiter.h"
@@ -48,7 +49,6 @@
#include "stack/include/l2cap_interface.h"
#include "stack/include/l2cdefs.h"
#include "stack/include/sdp_api.h"
-#include "stack/include/stack_metrics_logging.h"
#include "types/bluetooth/uuid.h"
#include "types/bt_transport.h"
#include "types/raw_address.h"
@@ -1476,7 +1476,8 @@ bool GATT_Connect(tGATT_IF gatt_if, const RawAddress& bd_addr, tBLE_ADDR_TYPE ad
return true;
}
- log_le_connection_lifecycle(ToGdAddress(bd_addr), true /* is_connect */, is_direct);
+ bluetooth::shim::LogMetricLeConnectionLifecycle(ToGdAddress(bd_addr), true /* is_connect */,
+ is_direct);
bool ret = false;
if (is_direct) {
@@ -1618,8 +1619,8 @@ tGATT_STATUS GATT_Disconnect(tCONN_ID conn_id) {
return GATT_ILLEGAL_PARAMETER;
}
- log_le_connection_lifecycle(ToGdAddress(p_tcb->peer_bda), true /* is_connect */,
- false /* is_direct */);
+ bluetooth::shim::LogMetricLeConnectionLifecycle(ToGdAddress(p_tcb->peer_bda),
+ true /* is_connect */, false /* is_direct */);
tGATT_IF gatt_if = gatt_get_gatt_if(conn_id);
gatt_update_app_use_link_flag(gatt_if, p_tcb, false, true);
diff --git a/system/stack/hid/hidd_api.cc b/system/stack/hid/hidd_api.cc
index 169868bbfc..58d9bdc07a 100644
--- a/system/stack/hid/hidd_api.cc
+++ b/system/stack/hid/hidd_api.cc
@@ -38,13 +38,13 @@
#include "hidd_int.h"
#include "hiddefs.h"
#include "internal_include/bt_target.h"
+#include "main/shim/metrics_api.h"
#include "osi/include/allocator.h"
#include "stack/include/bt_psm_types.h"
#include "stack/include/bt_types.h"
#include "stack/include/bt_uuid16.h"
#include "stack/include/sdp_api.h"
#include "stack/include/sdpdefs.h"
-#include "stack/include/stack_metrics_logging.h"
#include "stack/sdp/sdp_discovery_db.h"
#include "types/raw_address.h"
@@ -83,12 +83,14 @@ tHID_STATUS HID_DevRegister(tHID_DEV_HOST_CALLBACK* host_cback) {
log::verbose("");
if (hd_cb.reg_flag) {
- log_counter_metrics(android::bluetooth::CodePathCounterKeyEnum::HIDD_ERR_ALREADY_REGISTERED, 1);
+ bluetooth::shim::CountCounterMetrics(
+ android::bluetooth::CodePathCounterKeyEnum::HIDD_ERR_ALREADY_REGISTERED, 1);
return HID_ERR_ALREADY_REGISTERED;
}
if (host_cback == NULL) {
- log_counter_metrics(android::bluetooth::CodePathCounterKeyEnum::HIDD_ERR_HOST_CALLBACK_NULL, 1);
+ bluetooth::shim::CountCounterMetrics(
+ android::bluetooth::CodePathCounterKeyEnum::HIDD_ERR_HOST_CALLBACK_NULL, 1);
return HID_ERR_INVALID_PARAM;
}
@@ -122,7 +124,7 @@ tHID_STATUS HID_DevDeregister(void) {
log::verbose("");
if (!hd_cb.reg_flag) {
- log_counter_metrics(
+ bluetooth::shim::CountCounterMetrics(
android::bluetooth::CodePathCounterKeyEnum::HIDD_ERR_NOT_REGISTERED_AT_DEREGISTER, 1);
return HID_ERR_NOT_REGISTERED;
}
@@ -263,9 +265,10 @@ tHID_STATUS HID_DevAddRecord(uint32_t handle, char* p_name, char* p_description,
if (desc_len > HIDD_APP_DESCRIPTOR_LEN) {
log::error("descriptor length = {}, larger than max {}", desc_len, HIDD_APP_DESCRIPTOR_LEN);
- log_counter_metrics(android::bluetooth::CodePathCounterKeyEnum::
- HIDD_ERR_NOT_REGISTERED_DUE_TO_DESCRIPTOR_LENGTH,
- 1);
+ bluetooth::shim::CountCounterMetrics(
+ android::bluetooth::CodePathCounterKeyEnum::
+ HIDD_ERR_NOT_REGISTERED_DUE_TO_DESCRIPTOR_LENGTH,
+ 1);
return HID_ERR_NOT_REGISTERED;
};
@@ -273,9 +276,10 @@ tHID_STATUS HID_DevAddRecord(uint32_t handle, char* p_name, char* p_description,
if (p_buf == NULL) {
log::error("Buffer allocation failure for size = {}", buf_len);
- log_counter_metrics(android::bluetooth::CodePathCounterKeyEnum::
- HIDD_ERR_NOT_REGISTERED_DUE_TO_BUFFER_ALLOCATION,
- 1);
+ bluetooth::shim::CountCounterMetrics(
+ android::bluetooth::CodePathCounterKeyEnum::
+ HIDD_ERR_NOT_REGISTERED_DUE_TO_BUFFER_ALLOCATION,
+ 1);
return HID_ERR_NOT_REGISTERED;
}
@@ -346,8 +350,8 @@ tHID_STATUS HID_DevAddRecord(uint32_t handle, char* p_name, char* p_description,
if (!result) {
log::error("failed to complete SDP record");
- log_counter_metrics(android::bluetooth::CodePathCounterKeyEnum::HIDD_ERR_NOT_REGISTERED_AT_SDP,
- 1);
+ bluetooth::shim::CountCounterMetrics(
+ android::bluetooth::CodePathCounterKeyEnum::HIDD_ERR_NOT_REGISTERED_AT_SDP, 1);
return HID_ERR_NOT_REGISTERED;
}
@@ -376,7 +380,7 @@ tHID_STATUS HID_DevSendReport(uint8_t channel, uint8_t type, uint8_t id, uint16_
return hidd_conn_send_data(HID_CHANNEL_INTR, HID_TRANS_DATA, HID_PAR_REP_TYPE_INPUT, id, len,
p_data);
}
- log_counter_metrics(
+ bluetooth::shim::CountCounterMetrics(
android::bluetooth::CodePathCounterKeyEnum::HIDD_ERR_INVALID_PARAM_SEND_REPORT, 1);
return HID_ERR_INVALID_PARAM;
}
@@ -444,19 +448,20 @@ tHID_STATUS HID_DevUnplugDevice(const RawAddress& addr) {
******************************************************************************/
tHID_STATUS HID_DevConnect(void) {
if (!hd_cb.reg_flag) {
- log_counter_metrics(
+ bluetooth::shim::CountCounterMetrics(
android::bluetooth::CodePathCounterKeyEnum::HIDD_ERR_NOT_REGISTERED_AT_CONNECT, 1);
return HID_ERR_NOT_REGISTERED;
}
if (!hd_cb.device.in_use) {
- log_counter_metrics(
+ bluetooth::shim::CountCounterMetrics(
android::bluetooth::CodePathCounterKeyEnum::HIDD_ERR_DEVICE_NOT_IN_USE_AT_CONNECT, 1);
return HID_ERR_INVALID_PARAM;
}
if (hd_cb.device.state != HIDD_DEV_NO_CONN) {
- log_counter_metrics(android::bluetooth::CodePathCounterKeyEnum::HIDD_ERR_ALREADY_CONN, 1);
+ bluetooth::shim::CountCounterMetrics(
+ android::bluetooth::CodePathCounterKeyEnum::HIDD_ERR_ALREADY_CONN, 1);
return HID_ERR_ALREADY_CONN;
}
@@ -474,13 +479,13 @@ tHID_STATUS HID_DevConnect(void) {
******************************************************************************/
tHID_STATUS HID_DevDisconnect(void) {
if (!hd_cb.reg_flag) {
- log_counter_metrics(
+ bluetooth::shim::CountCounterMetrics(
android::bluetooth::CodePathCounterKeyEnum::HIDD_ERR_NOT_REGISTERED_AT_DISCONNECT, 1);
return HID_ERR_NOT_REGISTERED;
}
if (!hd_cb.device.in_use) {
- log_counter_metrics(
+ bluetooth::shim::CountCounterMetrics(
android::bluetooth::CodePathCounterKeyEnum::HIDD_ERR_DEVICE_NOT_IN_USE_AT_DISCONNECT,
1);
return HID_ERR_INVALID_PARAM;
@@ -492,10 +497,11 @@ tHID_STATUS HID_DevDisconnect(void) {
tHID_STATUS ret = hidd_conn_disconnect();
hd_cb.device.conn.conn_state = HID_CONN_STATE_UNUSED;
hd_cb.callback(hd_cb.device.addr, HID_DHOST_EVT_CLOSE, HID_ERR_DISCONNECTING, NULL);
- log_counter_metrics(android::bluetooth::CodePathCounterKeyEnum::HIDD_ERR_DISCONNECTING, 1);
+ bluetooth::shim::CountCounterMetrics(
+ android::bluetooth::CodePathCounterKeyEnum::HIDD_ERR_DISCONNECTING, 1);
return ret;
}
- log_counter_metrics(
+ bluetooth::shim::CountCounterMetrics(
android::bluetooth::CodePathCounterKeyEnum::HIDD_ERR_NO_CONNECTION_AT_DISCONNECT, 1);
return HID_ERR_NO_CONNECTION;
}
@@ -565,7 +571,7 @@ tHID_STATUS HID_DevGetDevice(RawAddress* addr) {
if (hd_cb.device.in_use) {
*addr = hd_cb.device.addr;
} else {
- log_counter_metrics(
+ bluetooth::shim::CountCounterMetrics(
android::bluetooth::CodePathCounterKeyEnum::HIDD_ERR_NOT_REGISTERED_AT_GET_DEVICE, 1);
return HID_ERR_NOT_REGISTERED;
}
diff --git a/system/stack/hid/hidd_conn.cc b/system/stack/hid/hidd_conn.cc
index 7276af8acd..5f94c1c870 100644
--- a/system/stack/hid/hidd_conn.cc
+++ b/system/stack/hid/hidd_conn.cc
@@ -37,13 +37,13 @@
#include "hiddefs.h"
#include "internal_include/bt_target.h"
#include "l2cap_types.h"
+#include "main/shim/metrics_api.h"
#include "osi/include/allocator.h"
#include "stack/hid/hidd_int.h"
#include "stack/include/bt_hdr.h"
#include "stack/include/bt_psm_types.h"
#include "stack/include/l2cap_interface.h"
#include "stack/include/l2cdefs.h"
-#include "stack/include/stack_metrics_logging.h"
#include "types/bt_transport.h"
#include "types/raw_address.h"
@@ -300,7 +300,7 @@ static void hidd_l2cif_config_cfm(uint16_t cid, uint16_t /* initiator */, tL2CAP
log::warn("could not start L2CAP connection for INTR");
hd_cb.callback(hd_cb.device.addr, HID_DHOST_EVT_CLOSE, HID_ERR_L2CAP_FAILED, NULL);
- log_counter_metrics(
+ bluetooth::shim::CountCounterMetrics(
android::bluetooth::CodePathCounterKeyEnum::HIDD_ERR_L2CAP_NOT_STARTED_INCOMING, 1);
return;
} else {
@@ -577,8 +577,8 @@ tHID_STATUS hidd_conn_reg(void) {
HID_PSM_CONTROL, dev_reg_info, false /* enable_snoop */, nullptr, HID_DEV_MTU_SIZE, 0,
BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT)) {
log::error("HID Control (device) registration failed");
- log_counter_metrics(android::bluetooth::CodePathCounterKeyEnum::HIDD_ERR_L2CAP_FAILED_CONTROL,
- 1);
+ bluetooth::shim::CountCounterMetrics(
+ android::bluetooth::CodePathCounterKeyEnum::HIDD_ERR_L2CAP_FAILED_CONTROL, 1);
return HID_ERR_L2CAP_FAILED;
}
@@ -587,8 +587,8 @@ tHID_STATUS hidd_conn_reg(void) {
0, BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT)) {
stack::l2cap::get_interface().L2CA_Deregister(HID_PSM_CONTROL);
log::error("HID Interrupt (device) registration failed");
- log_counter_metrics(android::bluetooth::CodePathCounterKeyEnum::HIDD_ERR_L2CAP_FAILED_INTERRUPT,
- 1);
+ bluetooth::shim::CountCounterMetrics(
+ android::bluetooth::CodePathCounterKeyEnum::HIDD_ERR_L2CAP_FAILED_INTERRUPT, 1);
return HID_ERR_L2CAP_FAILED;
}
@@ -627,14 +627,15 @@ tHID_STATUS hidd_conn_initiate(void) {
if (!p_dev->in_use) {
log::warn("no virtual cable established");
- log_counter_metrics(
+ bluetooth::shim::CountCounterMetrics(
android::bluetooth::CodePathCounterKeyEnum::HIDD_ERR_NOT_REGISTERED_AT_INITIATE, 1);
return HID_ERR_NOT_REGISTERED;
}
if (p_dev->conn.conn_state != HID_CONN_STATE_UNUSED) {
log::warn("connection already in progress");
- log_counter_metrics(android::bluetooth::CodePathCounterKeyEnum::HIDD_ERR_CONN_IN_PROCESS, 1);
+ bluetooth::shim::CountCounterMetrics(
+ android::bluetooth::CodePathCounterKeyEnum::HIDD_ERR_CONN_IN_PROCESS, 1);
return HID_ERR_CONN_IN_PROCESS;
}
@@ -649,8 +650,8 @@ tHID_STATUS hidd_conn_initiate(void) {
HID_PSM_CONTROL, p_dev->addr, BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT)) == 0) {
log::warn("could not start L2CAP connection");
hd_cb.callback(hd_cb.device.addr, HID_DHOST_EVT_CLOSE, HID_ERR_L2CAP_FAILED, NULL);
- log_counter_metrics(android::bluetooth::CodePathCounterKeyEnum::HIDD_ERR_L2CAP_FAILED_INITIATE,
- 1);
+ bluetooth::shim::CountCounterMetrics(
+ android::bluetooth::CodePathCounterKeyEnum::HIDD_ERR_L2CAP_FAILED_INITIATE, 1);
} else {
p_dev->conn.conn_state = HID_CONN_STATE_CONNECTING_CTRL;
}
@@ -723,7 +724,7 @@ tHID_STATUS hidd_conn_send_data(uint8_t channel, uint8_t msg_type, uint8_t param
tHID_CONN* p_hcon = &hd_cb.device.conn;
if (p_hcon->conn_flags & HID_CONN_FLAGS_CONGESTED) {
- log_counter_metrics(
+ bluetooth::shim::CountCounterMetrics(
android::bluetooth::CodePathCounterKeyEnum::HIDD_ERR_CONGESTED_AT_FLAG_CHECK, 1);
return HID_ERR_CONGESTED;
}
@@ -744,13 +745,15 @@ tHID_STATUS hidd_conn_send_data(uint8_t channel, uint8_t msg_type, uint8_t param
}
break;
default:
- log_counter_metrics(android::bluetooth::CodePathCounterKeyEnum::HIDD_ERR_INVALID_PARAM, 1);
+ bluetooth::shim::CountCounterMetrics(
+ android::bluetooth::CodePathCounterKeyEnum::HIDD_ERR_INVALID_PARAM, 1);
return HID_ERR_INVALID_PARAM;
}
p_buf = (BT_HDR*)osi_malloc(buf_size);
if (p_buf == NULL) {
- log_counter_metrics(android::bluetooth::CodePathCounterKeyEnum::HIDD_ERR_NO_RESOURCES, 1);
+ bluetooth::shim::CountCounterMetrics(
+ android::bluetooth::CodePathCounterKeyEnum::HIDD_ERR_NO_RESOURCES, 1);
return HID_ERR_NO_RESOURCES;
}
@@ -792,7 +795,7 @@ tHID_STATUS hidd_conn_send_data(uint8_t channel, uint8_t msg_type, uint8_t param
return HID_SUCCESS;
}
- log_counter_metrics(
+ bluetooth::shim::CountCounterMetrics(
android::bluetooth::CodePathCounterKeyEnum::HIDD_ERR_NO_CONNECTION_AT_SEND_DATA, 1);
return HID_ERR_NO_CONNECTION;
}
@@ -800,7 +803,7 @@ tHID_STATUS hidd_conn_send_data(uint8_t channel, uint8_t msg_type, uint8_t param
log::verbose("report sent");
if (stack::l2cap::get_interface().L2CA_DataWrite(cid, p_buf) == tL2CAP_DW_RESULT::FAILED) {
- log_counter_metrics(
+ bluetooth::shim::CountCounterMetrics(
android::bluetooth::CodePathCounterKeyEnum::HIDD_ERR_CONGESTED_AT_DATA_WRITE, 1);
return HID_ERR_CONGESTED;
}
diff --git a/system/stack/hid/hidh_api.cc b/system/stack/hid/hidh_api.cc
index 97d811ed5b..1ab5ba2a6a 100644
--- a/system/stack/hid/hidh_api.cc
+++ b/system/stack/hid/hidh_api.cc
@@ -37,6 +37,7 @@
#include "hiddefs.h"
#include "hidh_int.h"
#include "internal_include/bt_target.h"
+#include "main/shim/metrics_api.h"
#include "osi/include/alarm.h"
#include "osi/include/allocator.h"
#include "sdp_api.h"
@@ -44,7 +45,6 @@
#include "stack/include/bt_hdr.h"
#include "stack/include/bt_uuid16.h"
#include "stack/include/sdpdefs.h"
-#include "stack/include/stack_metrics_logging.h"
#include "stack/sdp/sdp_discovery_db.h"
#include "types/bluetooth/uuid.h"
#include "types/raw_address.h"
@@ -69,7 +69,8 @@ static void hidh_search_callback(const RawAddress& bd_addr, tSDP_RESULT sdp_resu
tHID_STATUS HID_HostGetSDPRecord(const RawAddress& addr, tSDP_DISCOVERY_DB* p_db, uint32_t db_len,
tHID_HOST_SDP_CALLBACK* sdp_cback) {
if (hh_cb.sdp_busy) {
- log_counter_metrics(android::bluetooth::CodePathCounterKeyEnum::HIDH_ERR_SDP_BUSY, 1);
+ bluetooth::shim::CountCounterMetrics(
+ android::bluetooth::CodePathCounterKeyEnum::HIDH_ERR_SDP_BUSY, 1);
return HID_ERR_SDP_BUSY;
}
@@ -87,7 +88,8 @@ tHID_STATUS HID_HostGetSDPRecord(const RawAddress& addr, tSDP_DISCOVERY_DB* p_db
return HID_SUCCESS;
} else {
log::warn("Unable to start SDP service search request peer:{}", addr);
- log_counter_metrics(android::bluetooth::CodePathCounterKeyEnum::HIDH_ERR_NO_RESOURCES_SDP, 1);
+ bluetooth::shim::CountCounterMetrics(
+ android::bluetooth::CodePathCounterKeyEnum::HIDH_ERR_NO_RESOURCES_SDP, 1);
return HID_ERR_NO_RESOURCES;
}
}
@@ -289,12 +291,13 @@ tHID_STATUS HID_HostRegister(tHID_HOST_DEV_CALLBACK* dev_cback) {
tHID_STATUS st;
if (hh_cb.reg_flag) {
- log_counter_metrics(android::bluetooth::CodePathCounterKeyEnum::HIDH_ERR_ALREADY_REGISTERED, 1);
+ bluetooth::shim::CountCounterMetrics(
+ android::bluetooth::CodePathCounterKeyEnum::HIDH_ERR_ALREADY_REGISTERED, 1);
return HID_ERR_ALREADY_REGISTERED;
}
if (dev_cback == NULL) {
- log_counter_metrics(
+ bluetooth::shim::CountCounterMetrics(
android::bluetooth::CodePathCounterKeyEnum::HIDH_ERR_INVALID_PARAM_AT_HOST_REGISTER, 1);
return HID_ERR_INVALID_PARAM;
}
@@ -392,7 +395,7 @@ tHID_STATUS HID_HostAddDev(const RawAddress& addr, uint16_t attr_mask, uint8_t*
}
if (i == HID_HOST_MAX_DEVICES) {
- log_counter_metrics(
+ bluetooth::shim::CountCounterMetrics(
android::bluetooth::CodePathCounterKeyEnum::HIDH_ERR_NO_RESOURCES_ADD_DEVICE, 1);
return HID_ERR_NO_RESOURCES;
}
@@ -427,7 +430,7 @@ tHID_STATUS HID_HostRemoveDev(uint8_t dev_handle) {
}
if ((dev_handle >= HID_HOST_MAX_DEVICES) || (!hh_cb.devices[dev_handle].in_use)) {
- log_counter_metrics(
+ bluetooth::shim::CountCounterMetrics(
android::bluetooth::CodePathCounterKeyEnum::HIDH_ERR_INVALID_PARAM_AT_HOST_REMOVE_DEV,
1);
return HID_ERR_INVALID_PARAM;
@@ -457,13 +460,14 @@ tHID_STATUS HID_HostOpenDev(uint8_t dev_handle) {
}
if ((dev_handle >= HID_HOST_MAX_DEVICES) || (!hh_cb.devices[dev_handle].in_use)) {
- log_counter_metrics(
+ bluetooth::shim::CountCounterMetrics(
android::bluetooth::CodePathCounterKeyEnum::HIDH_ERR_INVALID_PARAM_AT_HOST_OPEN_DEV, 1);
return HID_ERR_INVALID_PARAM;
}
if (hh_cb.devices[dev_handle].state != HID_DEV_NO_CONN) {
- log_counter_metrics(android::bluetooth::CodePathCounterKeyEnum::HIDH_ERR_ALREADY_CONN, 1);
+ bluetooth::shim::CountCounterMetrics(
+ android::bluetooth::CodePathCounterKeyEnum::HIDH_ERR_ALREADY_CONN, 1);
return HID_ERR_ALREADY_CONN;
}
@@ -494,13 +498,13 @@ tHID_STATUS HID_HostWriteDev(uint8_t dev_handle, uint8_t t_type, uint8_t param,
if ((dev_handle >= HID_HOST_MAX_DEVICES) || (!hh_cb.devices[dev_handle].in_use)) {
log::error("HID_ERR_INVALID_PARAM");
- log_counter_metrics(
+ bluetooth::shim::CountCounterMetrics(
android::bluetooth::CodePathCounterKeyEnum::HIDH_ERR_INVALID_PARAM_AT_HOST_WRITE_DEV,
1);
status = HID_ERR_INVALID_PARAM;
} else if (hh_cb.devices[dev_handle].state != HID_DEV_CONNECTED) {
log::error("HID_ERR_NO_CONNECTION dev_handle {}", dev_handle);
- log_counter_metrics(
+ bluetooth::shim::CountCounterMetrics(
android::bluetooth::CodePathCounterKeyEnum::HIDH_ERR_NO_CONNECTION_AT_HOST_WRITE_DEV,
1);
status = HID_ERR_NO_CONNECTION;
@@ -530,14 +534,14 @@ tHID_STATUS HID_HostCloseDev(uint8_t dev_handle) {
}
if ((dev_handle >= HID_HOST_MAX_DEVICES) || (!hh_cb.devices[dev_handle].in_use)) {
- log_counter_metrics(
+ bluetooth::shim::CountCounterMetrics(
android::bluetooth::CodePathCounterKeyEnum::HIDH_ERR_INVALID_PARAM_AT_HOST_CLOSE_DEV,
1);
return HID_ERR_INVALID_PARAM;
}
if (hh_cb.devices[dev_handle].state != HID_DEV_CONNECTED) {
- log_counter_metrics(
+ bluetooth::shim::CountCounterMetrics(
android::bluetooth::CodePathCounterKeyEnum::HIDH_ERR_NO_CONNECTION_AT_HOST_CLOSE_DEV,
1);
return HID_ERR_NO_CONNECTION;
diff --git a/system/stack/hid/hidh_conn.cc b/system/stack/hid/hidh_conn.cc
index cdc7906d16..71785478a1 100644
--- a/system/stack/hid/hidh_conn.cc
+++ b/system/stack/hid/hidh_conn.cc
@@ -39,6 +39,7 @@
#include "internal_include/bt_target.h"
#include "l2cap_types.h"
#include "l2cdefs.h"
+#include "main/shim/metrics_api.h"
#include "osi/include/alarm.h"
#include "osi/include/allocator.h"
#include "osi/include/osi.h"
@@ -48,7 +49,6 @@
#include "stack/include/btm_client_interface.h"
#include "stack/include/btm_log_history.h"
#include "stack/include/l2cap_interface.h"
-#include "stack/include/stack_metrics_logging.h"
#include "types/bt_transport.h"
#include "types/raw_address.h"
@@ -119,7 +119,7 @@ tHID_STATUS hidh_conn_reg(void) {
HID_PSM_CONTROL, hst_reg_info, false /* enable_snoop */, nullptr, HID_HOST_MTU, 0,
BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT)) {
log::error("HID-Host Control Registration failed");
- log_counter_metrics(
+ bluetooth::shim::CountCounterMetrics(
android::bluetooth::CodePathCounterKeyEnum::HIDH_ERR_L2CAP_FAILED_AT_REGISTER_CONTROL,
1);
return HID_ERR_L2CAP_FAILED;
@@ -129,7 +129,7 @@ tHID_STATUS hidh_conn_reg(void) {
BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT)) {
stack::l2cap::get_interface().L2CA_Deregister(HID_PSM_CONTROL);
log::error("HID-Host Interrupt Registration failed");
- log_counter_metrics(
+ bluetooth::shim::CountCounterMetrics(
android::bluetooth::CodePathCounterKeyEnum::HIDH_ERR_L2CAP_FAILED_AT_REGISTER_INTERRUPT,
1);
return HID_ERR_L2CAP_FAILED;
@@ -549,7 +549,8 @@ static void hidh_l2cif_disconnect_ind(uint16_t l2cap_cid, bool ack_needed) {
(disc_res == HCI_ERR_PAIRING_WITH_UNIT_KEY_NOT_SUPPORTED) ||
(disc_res == HCI_ERR_ENCRY_MODE_NOT_ACCEPTABLE) ||
(disc_res == HCI_ERR_REPEATED_ATTEMPTS)) {
- log_counter_metrics(android::bluetooth::CodePathCounterKeyEnum::HIDH_ERR_AUTH_FAILED, 1);
+ bluetooth::shim::CountCounterMetrics(
+ android::bluetooth::CodePathCounterKeyEnum::HIDH_ERR_AUTH_FAILED, 1);
hid_close_evt_reason = HID_ERR_AUTH_FAILED;
}
@@ -771,14 +772,14 @@ tHID_STATUS hidh_conn_snd_data(uint8_t dhandle, uint8_t trans_type, uint8_t para
if (!get_btm_client_interface().peer.BTM_IsAclConnectionUp(hh_cb.devices[dhandle].addr,
BT_TRANSPORT_BR_EDR)) {
osi_free(buf);
- log_counter_metrics(
+ bluetooth::shim::CountCounterMetrics(
android::bluetooth::CodePathCounterKeyEnum::HIDH_ERR_NO_CONNECTION_AT_SEND_DATA, 1);
return HID_ERR_NO_CONNECTION;
}
if (p_hcon->conn_flags & HID_CONN_FLAGS_CONGESTED) {
osi_free(buf);
- log_counter_metrics(
+ bluetooth::shim::CountCounterMetrics(
android::bluetooth::CodePathCounterKeyEnum::HIDH_ERR_CONGESTED_AT_FLAG_CHECK, 1);
return HID_ERR_CONGESTED;
}
@@ -799,7 +800,7 @@ tHID_STATUS hidh_conn_snd_data(uint8_t dhandle, uint8_t trans_type, uint8_t para
buf_size = HID_INTERRUPT_BUF_SIZE;
break;
default:
- log_counter_metrics(
+ bluetooth::shim::CountCounterMetrics(
android::bluetooth::CodePathCounterKeyEnum::HIDH_ERR_INVALID_PARAM_AT_SEND_DATA, 1);
return HID_ERR_INVALID_PARAM;
}
@@ -860,7 +861,7 @@ tHID_STATUS hidh_conn_snd_data(uint8_t dhandle, uint8_t trans_type, uint8_t para
/* Send the buffer through L2CAP */
if ((p_hcon->conn_flags & HID_CONN_FLAGS_CONGESTED) ||
(stack::l2cap::get_interface().L2CA_DataWrite(cid, p_buf) == tL2CAP_DW_RESULT::FAILED)) {
- log_counter_metrics(
+ bluetooth::shim::CountCounterMetrics(
android::bluetooth::CodePathCounterKeyEnum::HIDH_ERR_CONGESTED_AT_SEND_DATA, 1);
return HID_ERR_CONGESTED;
}
@@ -889,7 +890,8 @@ tHID_STATUS hidh_conn_initiate(uint8_t dhandle) {
tHID_HOST_DEV_CTB* p_dev = &hh_cb.devices[dhandle];
if (p_dev->conn.conn_state != HID_CONN_STATE_UNUSED) {
- log_counter_metrics(android::bluetooth::CodePathCounterKeyEnum::HIDH_ERR_CONN_IN_PROCESS, 1);
+ bluetooth::shim::CountCounterMetrics(
+ android::bluetooth::CodePathCounterKeyEnum::HIDH_ERR_CONN_IN_PROCESS, 1);
return HID_ERR_CONN_IN_PROCESS;
}
@@ -908,7 +910,7 @@ tHID_STATUS hidh_conn_initiate(uint8_t dhandle) {
log::warn("HID-Host Originate failed");
hh_cb.callback(dhandle, hh_cb.devices[dhandle].addr, HID_HDEV_EVT_CLOSE, HID_ERR_L2CAP_FAILED,
NULL);
- log_counter_metrics(
+ bluetooth::shim::CountCounterMetrics(
android::bluetooth::CodePathCounterKeyEnum::HIDH_ERR_L2CAP_FAILED_AT_INITIATE, 1);
} else {
/* Transition to the next appropriate state, waiting for connection confirm
diff --git a/system/stack/include/stack_metrics_logging.h b/system/stack/include/stack_metrics_logging.h
deleted file mode 100644
index 9a0a80baa4..0000000000
--- a/system/stack/include/stack_metrics_logging.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright 2021 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.
- */
-
-#pragma once
-
-#include <frameworks/proto_logging/stats/enums/bluetooth/enums.pb.h>
-#include <frameworks/proto_logging/stats/enums/bluetooth/hci/enums.pb.h>
-
-#include <cstdint>
-
-#include "hci/address.h"
-#include "hci/hci_packets.h"
-#include "types/raw_address.h"
-
-void log_classic_pairing_event(const RawAddress& address, uint16_t handle, uint32_t hci_cmd,
- uint16_t hci_event, uint16_t cmd_status, uint16_t reason_code,
- int64_t event_value);
-
-void log_link_layer_connection_event(const RawAddress* address, uint32_t connection_handle,
- android::bluetooth::DirectionEnum direction,
- uint16_t link_type, uint32_t hci_cmd, uint16_t hci_event,
- uint16_t hci_ble_event, uint16_t cmd_status,
- uint16_t reason_code);
-
-void log_smp_pairing_event(const RawAddress& address, uint16_t smp_cmd,
- android::bluetooth::DirectionEnum direction, uint16_t smp_fail_reason);
-
-void log_sdp_attribute(const RawAddress& address, uint16_t protocol_uuid, uint16_t attribute_id,
- size_t attribute_size, const char* attribute_value);
-
-void log_manufacturer_info(const RawAddress& address,
- android::bluetooth::AddressTypeEnum address_type,
- android::bluetooth::DeviceInfoSrcEnum source_type,
- const std::string& source_name, const std::string& manufacturer,
- const std::string& model, const std::string& hardware_version,
- const std::string& software_version);
-
-void log_counter_metrics(android::bluetooth::CodePathCounterKeyEnum key, int64_t value);
-
-void log_hfp_audio_packet_loss_stats(const RawAddress& address, int num_decoded_frames,
- double packet_loss_ratio, uint16_t codec_type);
-
-void log_mmc_transcode_rtt_stats(int maximum_rtt, double mean_rtt, int num_requests,
- int codec_type);
-
-void log_le_pairing_fail(const RawAddress& raw_address, uint8_t failure_reason, bool is_outgoing);
-
-void log_le_connection_status(bluetooth::hci::Address address, bool is_connect,
- bluetooth::hci::ErrorCode reason);
-
-void log_le_device_in_accept_list(bluetooth::hci::Address address, bool is_add);
-
-void log_le_connection_lifecycle(bluetooth::hci::Address address, bool is_connect, bool is_direct);
-
-void log_le_connection_completion(bluetooth::hci::Address address, bluetooth::hci::ErrorCode reason,
- bool is_locally_initiated);
diff --git a/system/stack/l2cap/l2c_ble.cc b/system/stack/l2cap/l2c_ble.cc
index 49dca969dc..d964271002 100644
--- a/system/stack/l2cap/l2c_ble.cc
+++ b/system/stack/l2cap/l2c_ble.cc
@@ -1443,7 +1443,7 @@ tL2CAP_LE_RESULT_CODE l2ble_sec_access_req(const RawAddress& bd_addr, uint16_t p
* constraints. For example, when there is at least one Hearing Aid device
* bonded, the minimum interval is raised. On return, min_interval and
* max_interval are updated. */
-void L2CA_AdjustConnectionIntervals(uint16_t* min_interval, uint16_t* max_interval,
+void L2CA_AdjustConnectionIntervals(uint16_t* /* min_interval */, uint16_t* max_interval,
uint16_t floor_interval) {
// Allow for customization by systemprops for mainline
uint16_t phone_min_interval = floor_interval;
@@ -1462,13 +1462,6 @@ void L2CA_AdjustConnectionIntervals(uint16_t* min_interval, uint16_t* max_interv
log::verbose("Have Hearing Aids. Min. interval is set to {}", phone_min_interval);
}
- if (!com::android::bluetooth::flags::l2cap_le_do_not_adjust_min_interval() &&
- *min_interval < phone_min_interval) {
- log::verbose("requested min_interval={} too small. Set to {}", *min_interval,
- phone_min_interval);
- *min_interval = phone_min_interval;
- }
-
// While this could result in connection parameters that fall
// outside fo the range requested, this will allow the connection
// to remain established.
diff --git a/system/stack/metrics/stack_metrics_logging.cc b/system/stack/metrics/stack_metrics_logging.cc
deleted file mode 100644
index 398a72ce33..0000000000
--- a/system/stack/metrics/stack_metrics_logging.cc
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright 2021 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.
- */
-
-#include "stack/include/stack_metrics_logging.h"
-
-#include <frameworks/proto_logging/stats/enums/bluetooth/enums.pb.h>
-#include <frameworks/proto_logging/stats/enums/bluetooth/hci/enums.pb.h>
-
-#include "common/metrics.h"
-#include "main/shim/metrics_api.h"
-#include "main/shim/shim.h"
-#include "types/raw_address.h"
-
-void log_classic_pairing_event(const RawAddress& address, uint16_t handle, uint32_t hci_cmd,
- uint16_t hci_event, uint16_t cmd_status, uint16_t reason_code,
- int64_t event_value) {
- bluetooth::shim::LogMetricClassicPairingEvent(address, handle, hci_cmd, hci_event, cmd_status,
- reason_code, event_value);
-}
-
-void log_link_layer_connection_event(const RawAddress* address, uint32_t connection_handle,
- android::bluetooth::DirectionEnum direction,
- uint16_t link_type, uint32_t hci_cmd, uint16_t hci_event,
- uint16_t hci_ble_event, uint16_t cmd_status,
- uint16_t reason_code) {
- bluetooth::shim::LogMetricLinkLayerConnectionEvent(address, connection_handle, direction,
- link_type, hci_cmd, hci_event, hci_ble_event,
- cmd_status, reason_code);
-}
-
-void log_smp_pairing_event(const RawAddress& address, uint16_t smp_cmd,
- android::bluetooth::DirectionEnum direction, uint16_t smp_fail_reason) {
- bluetooth::shim::LogMetricSmpPairingEvent(address, smp_cmd, direction, smp_fail_reason);
-}
-
-void log_sdp_attribute(const RawAddress& address, uint16_t protocol_uuid, uint16_t attribute_id,
- size_t attribute_size, const char* attribute_value) {
- bluetooth::shim::LogMetricSdpAttribute(address, protocol_uuid, attribute_id, attribute_size,
- attribute_value);
-}
-
-void log_manufacturer_info(const RawAddress& address,
- android::bluetooth::AddressTypeEnum address_type,
- android::bluetooth::DeviceInfoSrcEnum source_type,
- const std::string& source_name, const std::string& manufacturer,
- const std::string& model, const std::string& hardware_version,
- const std::string& software_version) {
- bluetooth::shim::LogMetricManufacturerInfo(address, address_type, source_type, source_name,
- manufacturer, model, hardware_version,
- software_version);
-}
-
-void log_counter_metrics(android::bluetooth::CodePathCounterKeyEnum key, int64_t value) {
- bluetooth::shim::CountCounterMetrics(key, value);
-}
-
-void log_hfp_audio_packet_loss_stats(const RawAddress& address, int num_decoded_frames,
- double packet_loss_ratio, uint16_t codec_type) {
- bluetooth::shim::LogMetricHfpPacketLossStats(address, num_decoded_frames, packet_loss_ratio,
- codec_type);
-}
-
-void log_mmc_transcode_rtt_stats(int maximum_rtt, double mean_rtt, int num_requests,
- int codec_type) {
- bluetooth::shim::LogMetricMmcTranscodeRttStats(maximum_rtt, mean_rtt, num_requests, codec_type);
-}
-
-void log_le_pairing_fail(const RawAddress& raw_address, uint8_t failure_reason, bool is_outgoing) {
- bluetooth::shim::LogMetricLePairingFail(raw_address, failure_reason, is_outgoing);
-}
-
-void log_le_connection_status(bluetooth::hci::Address address, bool is_connect,
- bluetooth::hci::ErrorCode reason) {
- bluetooth::shim::LogMetricLeConnectionStatus(address, is_connect, reason);
-}
-
-void log_le_device_in_accept_list(bluetooth::hci::Address address, bool is_add) {
- bluetooth::shim::LogMetricLeDeviceInAcceptList(address, is_add);
-}
-
-void log_le_connection_lifecycle(bluetooth::hci::Address address, bool is_connect, bool is_direct) {
- bluetooth::shim::LogMetricLeConnectionLifecycle(address, is_connect, is_direct);
-}
-
-void log_le_connection_completion(bluetooth::hci::Address address, bluetooth::hci::ErrorCode reason,
- bool is_locally_initiated) {
- bluetooth::shim::LogMetricLeConnectionCompletion(address, reason, is_locally_initiated);
-}
diff --git a/system/stack/mmc/metrics/mmc_rtt_logger.cc b/system/stack/mmc/metrics/mmc_rtt_logger.cc
index 761d825b44..c95566f0cb 100644
--- a/system/stack/mmc/metrics/mmc_rtt_logger.cc
+++ b/system/stack/mmc/metrics/mmc_rtt_logger.cc
@@ -20,7 +20,7 @@
#include <cmath>
#include <string>
-#include "stack/include/stack_metrics_logging.h"
+#include "main/shim/metrics_api.h"
namespace mmc {
@@ -43,7 +43,8 @@ void MmcRttLogger::UploadTranscodeRttStatics() {
if (num_requests_ == 0) {
return;
}
- log_mmc_transcode_rtt_stats(maximum_rtt_, rtt_sum_ / num_requests_, num_requests_, codec_type_);
+ bluetooth::shim::LogMetricMmcTranscodeRttStats(maximum_rtt_, rtt_sum_ / num_requests_,
+ num_requests_, codec_type_);
num_requests_ = 0;
rtt_sum_ = 0;
maximum_rtt_ = 0;
diff --git a/system/stack/rfcomm/port_api.cc b/system/stack/rfcomm/port_api.cc
index a78f3ea890..6ab7cdccea 100644
--- a/system/stack/rfcomm/port_api.cc
+++ b/system/stack/rfcomm/port_api.cc
@@ -1229,7 +1229,9 @@ int PORT_GetChannelInfo(uint16_t handle, uint16_t* local_mtu, uint16_t* remote_m
return PORT_NOT_OPENED;
}
- if (p_port->line_status) {
+ if (p_port->rfc.p_mcb == nullptr || p_port->line_status) {
+ log::warn("PORT_LINE_ERR - p_port->rfc.p_mcb == nullptr:{} p_port->line_status:{}",
+ (p_port->rfc.p_mcb == nullptr) ? "T" : "F", p_port->line_status);
return PORT_LINE_ERR;
}
diff --git a/system/stack/rfcomm/port_rfc.cc b/system/stack/rfcomm/port_rfc.cc
index 860fdf0450..c1518665d9 100644
--- a/system/stack/rfcomm/port_rfc.cc
+++ b/system/stack/rfcomm/port_rfc.cc
@@ -36,12 +36,12 @@
#include "internal_include/bt_target.h"
#include "internal_include/bt_trace.h"
#include "main/shim/entry.h"
+#include "main/shim/metrics_api.h"
#include "osi/include/allocator.h"
#include "osi/include/mutex.h"
#include "stack/include/bt_hdr.h"
#include "stack/include/bt_uuid16.h"
#include "stack/include/rfc_metrics.h"
-#include "stack/include/stack_metrics_logging.h"
#include "stack/l2cap/l2c_int.h"
#include "stack/rfcomm/port_int.h"
#include "stack/rfcomm/rfc_int.h"
@@ -186,7 +186,8 @@ void port_start_close(tPORT* p_port) {
* clear tPort */
if (p_port->p_mgmt_callback) {
p_port->p_mgmt_callback(PORT_CLOSED, p_port->handle);
- log_counter_metrics(android::bluetooth::CodePathCounterKeyEnum::RFCOMM_PORT_START_CLOSE, 1);
+ bluetooth::shim::CountCounterMetrics(
+ android::bluetooth::CodePathCounterKeyEnum::RFCOMM_PORT_START_CLOSE, 1);
}
port_release_port(p_port);
@@ -230,7 +231,7 @@ void PORT_StartCnf(tRFC_MCB* p_mcb, uint16_t result) {
if (p_port->p_mgmt_callback) {
p_port->p_mgmt_callback(PORT_START_FAILED, p_port->handle);
- log_counter_metrics(
+ bluetooth::shim::CountCounterMetrics(
android::bluetooth::CodePathCounterKeyEnum::RFCOMM_PORT_START_CNF_FAILED, 1);
}
port_release_port(p_port);
@@ -457,14 +458,14 @@ void PORT_DlcEstablishInd(tRFC_MCB* p_mcb, uint8_t dlci, uint16_t mtu) {
if (p_port->rfc_cfg_info.data_path != BTSOCK_DATA_PATH_HARDWARE_OFFLOAD &&
p_port->p_mgmt_callback) {
p_port->p_mgmt_callback(PORT_SUCCESS, p_port->handle);
- log_counter_metrics(android::bluetooth::CodePathCounterKeyEnum::RFCOMM_CONNECTION_SUCCESS_IND,
- 1);
+ bluetooth::shim::CountCounterMetrics(
+ android::bluetooth::CodePathCounterKeyEnum::RFCOMM_CONNECTION_SUCCESS_IND, 1);
}
} else {
if (p_port->p_mgmt_callback) {
p_port->p_mgmt_callback(PORT_SUCCESS, p_port->handle);
- log_counter_metrics(android::bluetooth::CodePathCounterKeyEnum::RFCOMM_CONNECTION_SUCCESS_IND,
- 1);
+ bluetooth::shim::CountCounterMetrics(
+ android::bluetooth::CodePathCounterKeyEnum::RFCOMM_CONNECTION_SUCCESS_IND, 1);
}
}
@@ -493,7 +494,8 @@ void PORT_DlcEstablishCnf(tRFC_MCB* p_mcb, uint8_t dlci, uint16_t mtu, uint16_t
if (result != RFCOMM_SUCCESS) {
log::warn("Unable to establish configuration dlci:{} result:{}", dlci, result);
port_rfc_closed(p_port, PORT_START_FAILED);
- log_counter_metrics(android::bluetooth::CodePathCounterKeyEnum::RFCOMM_PORT_START_FAILED, 1);
+ bluetooth::shim::CountCounterMetrics(
+ android::bluetooth::CodePathCounterKeyEnum::RFCOMM_PORT_START_FAILED, 1);
return;
}
@@ -513,14 +515,14 @@ void PORT_DlcEstablishCnf(tRFC_MCB* p_mcb, uint8_t dlci, uint16_t mtu, uint16_t
if (p_port->rfc_cfg_info.data_path != BTSOCK_DATA_PATH_HARDWARE_OFFLOAD &&
p_port->p_mgmt_callback) {
p_port->p_mgmt_callback(PORT_SUCCESS, p_port->handle);
- log_counter_metrics(android::bluetooth::CodePathCounterKeyEnum::RFCOMM_CONNECTION_SUCCESS_CNF,
- 1);
+ bluetooth::shim::CountCounterMetrics(
+ android::bluetooth::CodePathCounterKeyEnum::RFCOMM_CONNECTION_SUCCESS_CNF, 1);
}
} else {
if (p_port->p_mgmt_callback) {
p_port->p_mgmt_callback(PORT_SUCCESS, p_port->handle);
- log_counter_metrics(android::bluetooth::CodePathCounterKeyEnum::RFCOMM_CONNECTION_SUCCESS_CNF,
- 1);
+ bluetooth::shim::CountCounterMetrics(
+ android::bluetooth::CodePathCounterKeyEnum::RFCOMM_CONNECTION_SUCCESS_CNF, 1);
}
}
@@ -590,7 +592,8 @@ void PORT_PortNegCnf(tRFC_MCB* p_mcb, uint8_t dlci, PortSettings* /* p_settings
RFCOMM_DlcReleaseReq(p_mcb, p_port->dlci);
port_rfc_closed(p_port, PORT_PORT_NEG_FAILED);
- log_counter_metrics(android::bluetooth::CodePathCounterKeyEnum::RFCOMM_PORT_NEG_FAILED, 1);
+ bluetooth::shim::CountCounterMetrics(
+ android::bluetooth::CodePathCounterKeyEnum::RFCOMM_PORT_NEG_FAILED, 1);
return;
}
@@ -661,7 +664,7 @@ void PORT_ControlInd(tRFC_MCB* p_mcb, uint8_t dlci, tPORT_CTRL* p_pars) {
if (p_port->rfc_cfg_info.data_path == BTSOCK_DATA_PATH_HARDWARE_OFFLOAD) {
if (p_port->port_ctrl == PORT_CTRL_SETUP_COMPLETED && p_port->p_mgmt_callback) {
p_port->p_mgmt_callback(PORT_SUCCESS, p_port->handle);
- log_counter_metrics(
+ bluetooth::shim::CountCounterMetrics(
android::bluetooth::CodePathCounterKeyEnum::RFCOMM_CONNECTION_SUCCESS_IND, 1);
}
}
@@ -708,7 +711,7 @@ void PORT_ControlCnf(tRFC_MCB* p_mcb, uint8_t dlci, tPORT_CTRL* /* p_pars */) {
if (p_port->rfc_cfg_info.data_path == BTSOCK_DATA_PATH_HARDWARE_OFFLOAD) {
if (p_port->port_ctrl == PORT_CTRL_SETUP_COMPLETED && p_port->p_mgmt_callback) {
p_port->p_mgmt_callback(PORT_SUCCESS, p_port->handle);
- log_counter_metrics(
+ bluetooth::shim::CountCounterMetrics(
android::bluetooth::CodePathCounterKeyEnum::RFCOMM_CONNECTION_SUCCESS_CNF, 1);
}
}
@@ -767,7 +770,8 @@ void PORT_DlcReleaseInd(tRFC_MCB* p_mcb, uint8_t dlci) {
return;
}
port_rfc_closed(p_port, PORT_CLOSED);
- log_counter_metrics(android::bluetooth::CodePathCounterKeyEnum::RFCOMM_PORT_CLOSED, 1);
+ bluetooth::shim::CountCounterMetrics(
+ android::bluetooth::CodePathCounterKeyEnum::RFCOMM_PORT_CLOSED, 1);
}
/*******************************************************************************
@@ -788,7 +792,7 @@ void PORT_CloseInd(tRFC_MCB* p_mcb) {
for (i = 0; i < MAX_RFC_PORTS; i++, p_port++) {
if (p_port->rfc.p_mcb == p_mcb) {
port_rfc_closed(p_port, PORT_PEER_CONNECTION_FAILED);
- log_counter_metrics(
+ bluetooth::shim::CountCounterMetrics(
android::bluetooth::CodePathCounterKeyEnum::RFCOMM_PORT_PEER_CONNECTION_FAILED, 1);
}
}
@@ -813,7 +817,8 @@ void PORT_TimeOutCloseMux(tRFC_MCB* p_mcb) {
for (i = 0; i < MAX_RFC_PORTS; i++, p_port++) {
if (p_port->rfc.p_mcb == p_mcb) {
port_rfc_closed(p_port, PORT_PEER_TIMEOUT);
- log_counter_metrics(android::bluetooth::CodePathCounterKeyEnum::RFCOMM_PORT_PEER_TIMEOUT, 1);
+ bluetooth::shim::CountCounterMetrics(
+ android::bluetooth::CodePathCounterKeyEnum::RFCOMM_PORT_PEER_TIMEOUT, 1);
}
}
}
diff --git a/system/stack/rfcomm/rfc_l2cap_if.cc b/system/stack/rfcomm/rfc_l2cap_if.cc
index 5b7fc00185..10826d235a 100644
--- a/system/stack/rfcomm/rfc_l2cap_if.cc
+++ b/system/stack/rfcomm/rfc_l2cap_if.cc
@@ -91,28 +91,26 @@ void rfcomm_l2cap_if_init(void) {
void RFCOMM_ConnectInd(const RawAddress& bd_addr, uint16_t lcid, uint16_t /* psm */, uint8_t id) {
tRFC_MCB* p_mcb = rfc_alloc_multiplexer_channel(bd_addr, false);
- if ((p_mcb) && (p_mcb->state != RFC_MX_STATE_IDLE)) {
- /* if this is collision case */
- if ((p_mcb->is_initiator) && (p_mcb->state == RFC_MX_STATE_WAIT_CONN_CNF)) {
- p_mcb->pending_lcid = lcid;
-
- /* wait random timeout (2 - 12) to resolve collision */
- /* if peer gives up then local device rejects incoming connection and
- * continues as initiator */
- /* if timeout, local device disconnects outgoing connection and continues
- * as acceptor */
- log::verbose(
- "RFCOMM_ConnectInd start timer for collision, initiator's "
- "LCID(0x{:x}), acceptor's LCID(0x{:x})",
- p_mcb->lcid, p_mcb->pending_lcid);
-
- rfc_timer_start(p_mcb, (uint16_t)(bluetooth::common::time_get_os_boottime_ms() % 10 + 2));
- return;
- } else {
- /* we cannot accept connection request from peer at this state */
- /* don't update lcid */
- p_mcb = nullptr;
- }
+ if (p_mcb != nullptr && p_mcb->is_initiator && p_mcb->state == RFC_MX_STATE_WAIT_CONN_CNF) {
+ p_mcb->pending_lcid = lcid;
+
+ /* wait random timeout (2 - 12) to resolve collision */
+ /* if peer gives up then local device rejects incoming connection and
+ * continues as initiator */
+ /* if timeout, local device disconnects outgoing connection and continues
+ * as acceptor */
+ log::verbose(
+ "RFCOMM_ConnectInd start timer for collision, initiator's "
+ "LCID(0x{:x}), acceptor's LCID(0x{:x})",
+ p_mcb->lcid, p_mcb->pending_lcid);
+
+ rfc_timer_start(p_mcb, (uint16_t)(bluetooth::common::time_get_os_boottime_ms() % 10 + 2));
+ return;
+ }
+ if (p_mcb != nullptr && p_mcb->is_initiator && p_mcb->state != RFC_MX_STATE_IDLE) {
+ /* we cannot accept connection request from peer at this state */
+ /* don't update lcid */
+ p_mcb = nullptr;
} else {
/* store mcb even if null */
rfc_save_lcid_mcb(p_mcb, lcid);
@@ -141,7 +139,7 @@ void RFCOMM_ConnectInd(const RawAddress& bd_addr, uint16_t lcid, uint16_t /* psm
void RFCOMM_ConnectCnf(uint16_t lcid, tL2CAP_CONN result) {
tRFC_MCB* p_mcb = rfc_find_lcid_mcb(lcid);
- if (!p_mcb) {
+ if (p_mcb == nullptr) {
log::error("RFCOMM_ConnectCnf LCID:0x{:x}", lcid);
return;
}
@@ -188,7 +186,7 @@ void RFCOMM_ConfigInd(uint16_t lcid, tL2CAP_CFG_INFO* p_cfg) {
tRFC_MCB* p_mcb = rfc_find_lcid_mcb(lcid);
- if (!p_mcb) {
+ if (p_mcb == nullptr) {
log::error("RFCOMM_ConfigInd LCID:0x{:x}", lcid);
for (auto& [cid, mcb] : rfc_lcid_mcb) {
if (mcb != nullptr && mcb->pending_lcid == lcid) {
@@ -218,7 +216,7 @@ void RFCOMM_ConfigCnf(uint16_t lcid, uint16_t /* initiator */, tL2CAP_CFG_INFO*
tRFC_MCB* p_mcb = rfc_find_lcid_mcb(lcid);
- if (!p_mcb) {
+ if (p_mcb == nullptr) {
log::error("RFCOMM_ConfigCnf no MCB LCID:0x{:x}", lcid);
return;
}
@@ -237,7 +235,7 @@ void RFCOMM_ConfigCnf(uint16_t lcid, uint16_t /* initiator */, tL2CAP_CFG_INFO*
void RFCOMM_DisconnectInd(uint16_t lcid, bool is_conf_needed) {
log::verbose("lcid:0x{:x}, is_conf_needed:{}", lcid, is_conf_needed);
tRFC_MCB* p_mcb = rfc_find_lcid_mcb(lcid);
- if (!p_mcb) {
+ if (p_mcb == nullptr) {
log::warn("no mcb for lcid 0x{:x}", lcid);
return;
}
@@ -257,7 +255,7 @@ void RFCOMM_DisconnectInd(uint16_t lcid, bool is_conf_needed) {
void RFCOMM_BufDataInd(uint16_t lcid, BT_HDR* p_buf) {
tRFC_MCB* p_mcb = rfc_find_lcid_mcb(lcid);
- if (!p_mcb) {
+ if (p_mcb == nullptr) {
log::warn("Cannot find RFCOMM multiplexer for lcid 0x{:x}", lcid);
osi_free(p_buf);
return;
@@ -351,7 +349,7 @@ void RFCOMM_BufDataInd(uint16_t lcid, BT_HDR* p_buf) {
void RFCOMM_CongestionStatusInd(uint16_t lcid, bool is_congested) {
tRFC_MCB* p_mcb = rfc_find_lcid_mcb(lcid);
- if (!p_mcb) {
+ if (p_mcb == nullptr) {
log::error("RFCOMM_CongestionStatusInd dropped LCID:0x{:x}", lcid);
return;
} else {
diff --git a/system/stack/sdp/sdp_utils.cc b/system/stack/sdp/sdp_utils.cc
index 2fb4f4622b..324f4dd06e 100644
--- a/system/stack/sdp/sdp_utils.cc
+++ b/system/stack/sdp/sdp_utils.cc
@@ -39,6 +39,7 @@
#include "device/include/interop.h"
#include "internal_include/bt_target.h"
#include "internal_include/bt_trace.h"
+#include "main/shim/metrics_api.h"
#include "osi/include/allocator.h"
#include "osi/include/properties.h"
#include "stack/include/avrc_api.h"
@@ -50,7 +51,6 @@
#include "stack/include/btm_sec_api_types.h"
#include "stack/include/l2cap_interface.h"
#include "stack/include/sdpdefs.h"
-#include "stack/include/stack_metrics_logging.h"
#include "stack/sdp/internal/sdp_api.h"
#include "stack/sdp/sdpint.h"
#include "storage/config_keys.h"
@@ -184,15 +184,15 @@ void sdpu_log_attribute_metrics(const RawAddress& bda, tSDP_DISCOVERY_DB* p_db)
}
// Log the existence of a profile role
// This can be different from Bluetooth Profile Descriptor List
- log_sdp_attribute(bda, service_uuid, 0, 0, nullptr);
+ bluetooth::shim::LogMetricSdpAttribute(bda, service_uuid, 0, 0, nullptr);
// Log profile version from Bluetooth Profile Descriptor List
auto uuid_version_array = sdpu_find_profile_version(p_rec);
for (const auto& uuid_version_pair : uuid_version_array) {
uint16_t profile_uuid = uuid_version_pair.first;
uint16_t version = uuid_version_pair.second;
auto version_array = to_little_endian_array(version);
- log_sdp_attribute(bda, profile_uuid, ATTR_ID_BT_PROFILE_DESC_LIST, version_array.size(),
- version_array.data());
+ bluetooth::shim::LogMetricSdpAttribute(bda, profile_uuid, ATTR_ID_BT_PROFILE_DESC_LIST,
+ version_array.size(), version_array.data());
}
// Log protocol version from Protocol Descriptor List
uint16_t protocol_uuid = 0;
@@ -217,8 +217,8 @@ void sdpu_log_attribute_metrics(const RawAddress& bda, tSDP_DISCOVERY_DB* p_db)
if (protocol_elements.num_params >= 1) {
uint16_t version = protocol_elements.params[0];
auto version_array = to_little_endian_array(version);
- log_sdp_attribute(bda, protocol_uuid, ATTR_ID_PROTOCOL_DESC_LIST, version_array.size(),
- version_array.data());
+ bluetooth::shim::LogMetricSdpAttribute(bda, protocol_uuid, ATTR_ID_PROTOCOL_DESC_LIST,
+ version_array.size(), version_array.data());
}
}
}
@@ -238,8 +238,8 @@ void sdpu_log_attribute_metrics(const RawAddress& bda, tSDP_DISCOVERY_DB* p_db)
}
uint16_t supported_features = p_attr->attr_value.v.u16;
auto version_array = to_little_endian_array(supported_features);
- log_sdp_attribute(bda, service_uuid, ATTR_ID_SUPPORTED_FEATURES, version_array.size(),
- version_array.data());
+ bluetooth::shim::LogMetricSdpAttribute(bda, service_uuid, ATTR_ID_SUPPORTED_FEATURES,
+ version_array.size(), version_array.data());
break;
}
case UUID_SERVCLASS_MESSAGE_NOTIFICATION:
@@ -251,8 +251,8 @@ void sdpu_log_attribute_metrics(const RawAddress& bda, tSDP_DISCOVERY_DB* p_db)
}
uint32_t map_supported_features = p_attr->attr_value.v.u32;
auto features_array = to_little_endian_array(map_supported_features);
- log_sdp_attribute(bda, service_uuid, ATTR_ID_MAP_SUPPORTED_FEATURES, features_array.size(),
- features_array.data());
+ bluetooth::shim::LogMetricSdpAttribute(bda, service_uuid, ATTR_ID_MAP_SUPPORTED_FEATURES,
+ features_array.size(), features_array.data());
break;
}
case UUID_SERVCLASS_PBAP_PCE:
@@ -264,8 +264,8 @@ void sdpu_log_attribute_metrics(const RawAddress& bda, tSDP_DISCOVERY_DB* p_db)
}
uint32_t pbap_supported_features = p_attr->attr_value.v.u32;
auto features_array = to_little_endian_array(pbap_supported_features);
- log_sdp_attribute(bda, service_uuid, ATTR_ID_PBAP_SUPPORTED_FEATURES, features_array.size(),
- features_array.data());
+ bluetooth::shim::LogMetricSdpAttribute(bda, service_uuid, ATTR_ID_PBAP_SUPPORTED_FEATURES,
+ features_array.size(), features_array.data());
break;
}
}
@@ -278,15 +278,17 @@ void sdpu_log_attribute_metrics(const RawAddress& bda, tSDP_DISCOVERY_DB* p_db)
tSDP_DI_GET_RECORD di_record = {};
if (SDP_GetDiRecord(1, &di_record, p_db) == tSDP_STATUS::SDP_SUCCESS) {
auto version_array = to_little_endian_array(di_record.spec_id);
- log_sdp_attribute(bda, UUID_SERVCLASS_PNP_INFORMATION, ATTR_ID_SPECIFICATION_ID,
- version_array.size(), version_array.data());
+ bluetooth::shim::LogMetricSdpAttribute(bda, UUID_SERVCLASS_PNP_INFORMATION,
+ ATTR_ID_SPECIFICATION_ID, version_array.size(),
+ version_array.data());
std::stringstream ss;
// [N - native]::SDP::[DIP - Device ID Profile]
ss << "N:SDP::DIP::" << loghex(di_record.rec.vendor_id_source);
- log_manufacturer_info(bda, android::bluetooth::AddressTypeEnum::ADDRESS_TYPE_PUBLIC,
- android::bluetooth::DeviceInfoSrcEnum::DEVICE_INFO_INTERNAL, ss.str(),
- loghex(di_record.rec.vendor), loghex(di_record.rec.product),
- loghex(di_record.rec.version), "");
+ bluetooth::shim::LogMetricManufacturerInfo(
+ bda, android::bluetooth::AddressTypeEnum::ADDRESS_TYPE_PUBLIC,
+ android::bluetooth::DeviceInfoSrcEnum::DEVICE_INFO_INTERNAL, ss.str(),
+ loghex(di_record.rec.vendor), loghex(di_record.rec.product),
+ loghex(di_record.rec.version), "");
std::string bda_string = bda.ToString();
// write manufacturer, model, HW version to config
diff --git a/system/stack/smp/smp_l2c.cc b/system/stack/smp/smp_l2c.cc
index 219cb723f7..69591b10e5 100644
--- a/system/stack/smp/smp_l2c.cc
+++ b/system/stack/smp/smp_l2c.cc
@@ -263,13 +263,6 @@ static void smp_br_connect_callback(uint16_t /* channel */, const RawAddress& bd
log::info("BDA:{} pairing_bda:{}, connected:{}", bd_addr, p_cb->pairing_bda, connected);
if (bd_addr != p_cb->pairing_bda) {
- if (!com::android::bluetooth::flags::smp_state_machine_stuck_after_disconnection_fix()) {
- log::info(
- "If your pairing failed, get a build with "
- "smp_state_machine_stuck_after_disconnection_fix and try again :)");
- return;
- }
-
tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bd_addr);
/* When pairing was initiated to RPA, and connection was on LE transport first using RPA, then
* we must check record pseudo address, it might be same device */
diff --git a/system/stack/smp/smp_utils.cc b/system/stack/smp/smp_utils.cc
index e5aefe3c6a..9be3de7db1 100644
--- a/system/stack/smp/smp_utils.cc
+++ b/system/stack/smp/smp_utils.cc
@@ -35,6 +35,7 @@
#include "internal_include/stack_config.h"
#include "main/shim/entry.h"
#include "main/shim/helpers.h"
+#include "main/shim/metrics_api.h"
#include "metrics/bluetooth_event.h"
#include "osi/include/allocator.h"
#include "p_256_ecc_pp.h"
@@ -51,7 +52,6 @@
#include "stack/include/l2cap_interface.h"
#include "stack/include/l2cdefs.h"
#include "stack/include/smp_status.h"
-#include "stack/include/stack_metrics_logging.h"
#include "types/raw_address.h"
#define SMP_PAIRING_REQ_SIZE 7
@@ -320,7 +320,7 @@ void smp_log_metrics(const RawAddress& bd_addr, bool is_outgoing, const uint8_t*
uint8_t failure_reason = 0;
if (raw_cmd == SMP_OPCODE_PAIRING_FAILED && buf_len >= 1) {
STREAM_TO_UINT8(failure_reason, p_buf);
- log_le_pairing_fail(bd_addr, failure_reason, is_outgoing);
+ bluetooth::shim::LogMetricLePairingFail(bd_addr, failure_reason, is_outgoing);
}
if (smp_cb.is_pair_cancel) {
failure_reason = SMP_USER_CANCELLED; // Tracking pairing cancellations
@@ -330,7 +330,8 @@ void smp_log_metrics(const RawAddress& bd_addr, bool is_outgoing, const uint8_t*
android::bluetooth::DirectionEnum direction =
is_outgoing ? android::bluetooth::DirectionEnum::DIRECTION_OUTGOING
: android::bluetooth::DirectionEnum::DIRECTION_INCOMING;
- log_smp_pairing_event(bd_addr, metric_cmd, direction, static_cast<uint16_t>(failure_reason));
+ bluetooth::shim::LogMetricSmpPairingEvent(bd_addr, metric_cmd, direction,
+ static_cast<uint16_t>(failure_reason));
}
/*******************************************************************************
@@ -1011,7 +1012,8 @@ void smp_proc_pairing_cmpl(tSMP_CB* p_cb) {
if (metric_status > SMP_MAX_FAIL_RSN_PER_SPEC) {
metric_status |= SMP_METRIC_STATUS_INTERNAL_FLAG;
}
- log_smp_pairing_event(p_cb->pairing_bda, metric_cmd, direction, metric_status);
+ bluetooth::shim::LogMetricSmpPairingEvent(p_cb->pairing_bda, metric_cmd, direction,
+ metric_status);
}
if (p_cb->status == SMP_SUCCESS && p_cb->smp_over_br) {
diff --git a/system/stack/test/btm/stack_btm_power_mode_test.cc b/system/stack/test/btm/stack_btm_power_mode_test.cc
index a3376d8649..ad7b27a71a 100644
--- a/system/stack/test/btm/stack_btm_power_mode_test.cc
+++ b/system/stack/test/btm/stack_btm_power_mode_test.cc
@@ -49,8 +49,10 @@ std::deque<power_mode_callback> power_mode_callback_queue;
class StackBtmPowerMode : public testing::Test {
protected:
void SetUp() override {
- ON_CALL(controller_, SupportsSniffMode).WillByDefault(Return(true));
- bluetooth::hci::testing::mock_controller_ = &controller_;
+ bluetooth::hci::testing::mock_controller_ =
+ std::make_unique<bluetooth::hci::testing::MockControllerInterface>();
+ ON_CALL(*bluetooth::hci::testing::mock_controller_, SupportsSniffMode)
+ .WillByDefault(Return(true));
power_mode_callback_queue.clear();
reset_mock_function_count_map();
ASSERT_EQ(tBTM_STATUS::BTM_SUCCESS,
@@ -71,10 +73,9 @@ protected:
BTM_PmRegister(BTM_PM_DEREG, &pm_id_,
[](const RawAddress& /* p_bda */, tBTM_PM_STATUS /* status */,
uint16_t /* value */, tHCI_STATUS /* hci_status */) {}));
- bluetooth::hci::testing::mock_controller_ = nullptr;
+ bluetooth::hci::testing::mock_controller_.reset();
}
- bluetooth::hci::testing::MockControllerInterface controller_;
uint8_t pm_id_{0};
};
diff --git a/system/stack/test/btm/stack_btm_sec_test.cc b/system/stack/test/btm/stack_btm_sec_test.cc
index 58317afc29..62226e2750 100644
--- a/system/stack/test/btm/stack_btm_sec_test.cc
+++ b/system/stack/test/btm/stack_btm_sec_test.cc
@@ -69,7 +69,8 @@ protected:
down_thread_ =
new bluetooth::os::Thread("down_thread", bluetooth::os::Thread::Priority::NORMAL);
down_handler_ = new bluetooth::os::Handler(down_thread_);
- bluetooth::hci::testing::mock_hci_layer_ = &mock_hci_;
+ bluetooth::hci::testing::mock_hci_layer_ =
+ std::make_unique<bluetooth::hci::testing::MockHciLayer>();
bluetooth::hci::testing::mock_gd_shim_handler_ = up_handler_;
}
void TearDown() override {
@@ -79,10 +80,10 @@ protected:
down_handler_->Clear();
delete down_handler_;
delete down_thread_;
+ bluetooth::hci::testing::mock_hci_layer_.reset();
StackBtmSecTest::TearDown();
}
bluetooth::common::BidiQueue<bluetooth::hci::ScoView, bluetooth::hci::ScoBuilder> sco_queue_{10};
- bluetooth::hci::testing::MockHciLayer mock_hci_;
bluetooth::os::Thread* up_thread_;
bluetooth::os::Handler* up_handler_;
bluetooth::os::Thread* down_thread_;
diff --git a/system/stack/test/btm/stack_btm_test.cc b/system/stack/test/btm/stack_btm_test.cc
index 7471d4faca..2341b21677 100644
--- a/system/stack/test/btm/stack_btm_test.cc
+++ b/system/stack/test/btm/stack_btm_test.cc
@@ -63,13 +63,13 @@ public:
protected:
void SetUp() override {
BtmWithMocksTest::SetUp();
- bluetooth::hci::testing::mock_controller_ = &controller_;
+ bluetooth::hci::testing::mock_controller_ =
+ std::make_unique<bluetooth::hci::testing::MockControllerInterface>();
}
void TearDown() override {
- bluetooth::hci::testing::mock_controller_ = nullptr;
+ bluetooth::hci::testing::mock_controller_.reset();
BtmWithMocksTest::TearDown();
}
- bluetooth::hci::testing::MockControllerInterface controller_;
};
class StackBtmWithQueuesTest : public StackBtmTest {
@@ -82,11 +82,12 @@ protected:
down_thread_ =
new bluetooth::os::Thread("down_thread", bluetooth::os::Thread::Priority::NORMAL);
down_handler_ = new bluetooth::os::Handler(down_thread_);
- bluetooth::hci::testing::mock_hci_layer_ = &mock_hci_;
+ bluetooth::hci::testing::mock_hci_layer_ =
+ std::make_unique<bluetooth::hci::testing::MockHciLayer>();
bluetooth::hci::testing::mock_gd_shim_handler_ = up_handler_;
bluetooth::legacy::hci::testing::SetMock(legacy_hci_mock_);
- EXPECT_CALL(mock_hci_, RegisterForScoConnectionRequests(_));
- EXPECT_CALL(mock_hci_, RegisterForDisconnects(_));
+ EXPECT_CALL(*bluetooth::hci::testing::mock_hci_layer_, RegisterForScoConnectionRequests(_));
+ EXPECT_CALL(*bluetooth::hci::testing::mock_hci_layer_, RegisterForDisconnects(_));
}
void TearDown() override {
up_handler_->Clear();
@@ -95,10 +96,10 @@ protected:
down_handler_->Clear();
delete down_handler_;
delete down_thread_;
+ bluetooth::hci::testing::mock_hci_layer_.release();
StackBtmTest::TearDown();
}
bluetooth::common::BidiQueue<bluetooth::hci::ScoView, bluetooth::hci::ScoBuilder> sco_queue_{10};
- bluetooth::hci::testing::MockHciLayer mock_hci_;
bluetooth::legacy::hci::testing::MockInterface legacy_hci_mock_;
bluetooth::os::Thread* up_thread_;
bluetooth::os::Handler* up_handler_;
@@ -111,7 +112,8 @@ public:
protected:
void SetUp() override {
StackBtmWithQueuesTest::SetUp();
- EXPECT_CALL(mock_hci_, GetScoQueueEnd()).WillOnce(Return(sco_queue_.GetUpEnd()));
+ EXPECT_CALL(*bluetooth::hci::testing::mock_hci_layer_, GetScoQueueEnd())
+ .WillOnce(Return(sco_queue_.GetUpEnd()));
btm_cb.Init();
btm_sec_cb.Init(BTM_SEC_MODE_SC);
}
@@ -123,7 +125,8 @@ protected:
};
TEST_F(StackBtmWithQueuesTest, GlobalLifecycle) {
- EXPECT_CALL(mock_hci_, GetScoQueueEnd()).WillOnce(Return(sco_queue_.GetUpEnd()));
+ EXPECT_CALL(*bluetooth::hci::testing::mock_hci_layer_, GetScoQueueEnd())
+ .WillOnce(Return(sco_queue_.GetUpEnd()));
get_btm_client_interface().lifecycle.btm_init();
get_btm_client_interface().lifecycle.btm_free();
}
@@ -134,20 +137,23 @@ TEST_F(StackBtmTest, DynamicLifecycle) {
}
TEST_F(StackBtmWithQueuesTest, InitFree) {
- EXPECT_CALL(mock_hci_, GetScoQueueEnd()).WillOnce(Return(sco_queue_.GetUpEnd()));
+ EXPECT_CALL(*bluetooth::hci::testing::mock_hci_layer_, GetScoQueueEnd())
+ .WillOnce(Return(sco_queue_.GetUpEnd()));
btm_cb.Init();
btm_cb.Free();
}
TEST_F(StackBtmWithQueuesTest, tSCO_CB) {
- EXPECT_CALL(mock_hci_, GetScoQueueEnd()).WillOnce(Return(sco_queue_.GetUpEnd()));
+ EXPECT_CALL(*bluetooth::hci::testing::mock_hci_layer_, GetScoQueueEnd())
+ .WillOnce(Return(sco_queue_.GetUpEnd()));
tSCO_CB* p_sco = &btm_cb.sco_cb;
p_sco->Init();
p_sco->Free();
}
TEST_F(StackBtmWithQueuesTest, InformClientOnConnectionSuccess) {
- EXPECT_CALL(mock_hci_, GetScoQueueEnd()).WillOnce(Return(sco_queue_.GetUpEnd()));
+ EXPECT_CALL(*bluetooth::hci::testing::mock_hci_layer_, GetScoQueueEnd())
+ .WillOnce(Return(sco_queue_.GetUpEnd()));
get_btm_client_interface().lifecycle.btm_init();
RawAddress bda({0x11, 0x22, 0x33, 0x44, 0x55, 0x66});
@@ -159,7 +165,8 @@ TEST_F(StackBtmWithQueuesTest, InformClientOnConnectionSuccess) {
}
TEST_F(StackBtmWithQueuesTest, NoInformClientOnConnectionFail) {
- EXPECT_CALL(mock_hci_, GetScoQueueEnd()).WillOnce(Return(sco_queue_.GetUpEnd()));
+ EXPECT_CALL(*bluetooth::hci::testing::mock_hci_layer_, GetScoQueueEnd())
+ .WillOnce(Return(sco_queue_.GetUpEnd()));
get_btm_client_interface().lifecycle.btm_init();
RawAddress bda({0x11, 0x22, 0x33, 0x44, 0x55, 0x66});
@@ -171,7 +178,8 @@ TEST_F(StackBtmWithQueuesTest, NoInformClientOnConnectionFail) {
}
TEST_F(StackBtmWithQueuesTest, default_packet_type) {
- EXPECT_CALL(mock_hci_, GetScoQueueEnd()).WillOnce(Return(sco_queue_.GetUpEnd()));
+ EXPECT_CALL(*bluetooth::hci::testing::mock_hci_layer_, GetScoQueueEnd())
+ .WillOnce(Return(sco_queue_.GetUpEnd()));
get_btm_client_interface().lifecycle.btm_init();
btm_cb.acl_cb_.SetDefaultPacketTypeMask(0x4321);
@@ -181,7 +189,8 @@ TEST_F(StackBtmWithQueuesTest, default_packet_type) {
}
TEST_F(StackBtmWithQueuesTest, change_packet_type) {
- EXPECT_CALL(mock_hci_, GetScoQueueEnd()).WillOnce(Return(sco_queue_.GetUpEnd()));
+ EXPECT_CALL(*bluetooth::hci::testing::mock_hci_layer_, GetScoQueueEnd())
+ .WillOnce(Return(sco_queue_.GetUpEnd()));
get_btm_client_interface().lifecycle.btm_init();
uint16_t handle = 0x123;
diff --git a/system/stack/test/btm_iso_test.cc b/system/stack/test/btm_iso_test.cc
index 40453f703d..b44f6fe094 100644
--- a/system/stack/test/btm_iso_test.cc
+++ b/system/stack/test/btm_iso_test.cc
@@ -134,7 +134,8 @@ protected:
bluetooth::shim::SetMockIsoInterface(&iso_interface_);
hcic::SetMockHcicInterface(&hcic_interface_);
bluetooth::shim::testing::hci_layer_set_interface(&bluetooth::shim::interface);
- bluetooth::hci::testing::mock_controller_ = &controller_;
+ bluetooth::hci::testing::mock_controller_ =
+ std::make_unique<bluetooth::hci::testing::MockControllerInterface>();
big_callbacks_.reset(new MockBigCallbacks());
cig_callbacks_.reset(new MockCigCallbacks());
@@ -142,7 +143,8 @@ protected:
iso_sizes_.total_num_le_packets_ = 6;
iso_sizes_.le_data_packet_length_ = 1024;
- ON_CALL(controller_, GetControllerIsoBufferSize()).WillByDefault(Return(iso_sizes_));
+ ON_CALL(*bluetooth::hci::testing::mock_controller_, GetControllerIsoBufferSize())
+ .WillByDefault(Return(iso_sizes_));
InitIsoManager();
}
@@ -156,7 +158,7 @@ protected:
bluetooth::shim::SetMockIsoInterface(nullptr);
hcic::SetMockHcicInterface(nullptr);
bluetooth::shim::testing::hci_layer_set_interface(nullptr);
- bluetooth::hci::testing::mock_controller_ = nullptr;
+ bluetooth::hci::testing::mock_controller_.reset();
}
virtual void InitIsoManager() {
@@ -312,7 +314,6 @@ protected:
IsoManager* manager_instance_;
bluetooth::shim::MockIsoInterface iso_interface_;
hcic::MockHcicInterface hcic_interface_;
- bluetooth::hci::testing::MockControllerInterface controller_;
bluetooth::hci::LeBufferSize iso_sizes_;
std::unique_ptr<MockBigCallbacks> big_callbacks_;
@@ -2207,7 +2208,8 @@ TEST_F(IsoManagerTest, SendIsoDataBigValid) {
}
TEST_F(IsoManagerTest, SendIsoDataNoCredits) {
- uint8_t num_buffers = controller_.GetControllerIsoBufferSize().total_num_le_packets_;
+ uint8_t num_buffers = bluetooth::hci::testing::mock_controller_->GetControllerIsoBufferSize()
+ .total_num_le_packets_;
std::vector<uint8_t> data_vec(108, 0);
// Check on CIG
@@ -2254,7 +2256,8 @@ TEST_F(IsoManagerTest, SendIsoDataNoCredits) {
}
TEST_F(IsoManagerTest, SendIsoDataCreditsReturned) {
- uint8_t num_buffers = controller_.GetControllerIsoBufferSize().total_num_le_packets_;
+ uint8_t num_buffers = bluetooth::hci::testing::mock_controller_->GetControllerIsoBufferSize()
+ .total_num_le_packets_;
std::vector<uint8_t> data_vec(108, 0);
// Check on CIG
@@ -2323,7 +2326,8 @@ TEST_F(IsoManagerTest, SendIsoDataCreditsReturned) {
}
TEST_F(IsoManagerTest, SendIsoDataCreditsReturnedByDisconnection) {
- uint8_t num_buffers = controller_.GetControllerIsoBufferSize().total_num_le_packets_;
+ uint8_t num_buffers = bluetooth::hci::testing::mock_controller_->GetControllerIsoBufferSize()
+ .total_num_le_packets_;
std::vector<uint8_t> data_vec(108, 0);
// Check on CIG
@@ -2542,7 +2546,8 @@ TEST_F(IsoManagerDeathTestNoCleanup, HandleLateArivingEventHandleDisconnect) {
* is already stopped.
*/
TEST_F(IsoManagerDeathTestNoCleanup, HandleLateArivingEventHandleNumComplDataPkts) {
- uint8_t num_buffers = controller_.GetControllerIsoBufferSize().total_num_le_packets_;
+ uint8_t num_buffers = bluetooth::hci::testing::mock_controller_->GetControllerIsoBufferSize()
+ .total_num_le_packets_;
IsoManager::GetInstance()->CreateCig(volatile_test_cig_create_cmpl_evt_.cig_id,
kDefaultCigParams);
diff --git a/system/stack/test/connection_manager_test.cc b/system/stack/test/connection_manager_test.cc
index 1a06158ca0..db2908c76b 100644
--- a/system/stack/test/connection_manager_test.cc
+++ b/system/stack/test/connection_manager_test.cc
@@ -70,9 +70,10 @@ namespace connection_manager {
class BleConnectionManager : public testing::Test {
void SetUp() override {
localConnTimeoutMock = std::make_unique<MockConnTimeout>();
- /* extern */ test::mock_acl_manager_ = new bluetooth::hci::testing::MockAclManager();
+ /* extern */ test::mock_acl_manager_ =
+ std::make_unique<bluetooth::hci::testing::MockAclManager>();
/* extern */ test::mock_controller_ =
- new testing::NiceMock<bluetooth::hci::testing::MockControllerInterface>();
+ std::make_unique<testing::NiceMock<bluetooth::hci::testing::MockControllerInterface>>();
ON_CALL(*test::mock_controller_, GetLeFilterAcceptListSize()).WillByDefault(Return(16));
auto alarm_mock = AlarmMock::Get();
@@ -92,8 +93,8 @@ class BleConnectionManager : public testing::Test {
void TearDown() override {
connection_manager::reset(true);
AlarmMock::Reset();
- delete test::mock_controller_;
- delete test::mock_acl_manager_;
+ test::mock_controller_.reset();
+ test::mock_acl_manager_.reset();
localConnTimeoutMock.reset();
}
};
@@ -106,7 +107,7 @@ TEST_F(BleConnectionManager, test_background_connection_add_remove) {
EXPECT_TRUE(background_connect_add(CLIENT1, address1));
- Mock::VerifyAndClearExpectations(test::mock_acl_manager_);
+ Mock::VerifyAndClearExpectations(test::mock_acl_manager_.get());
std::set<tAPP_ID> apps = get_apps_connecting_to(address1);
EXPECT_EQ(apps.size(), 1UL);
@@ -119,7 +120,7 @@ TEST_F(BleConnectionManager, test_background_connection_add_remove) {
EXPECT_EQ(get_apps_connecting_to(address1).size(), 0UL);
- Mock::VerifyAndClearExpectations(test::mock_acl_manager_);
+ Mock::VerifyAndClearExpectations(test::mock_acl_manager_.get());
}
/** Verify that multiple clients adding same device multiple times, result in
@@ -136,7 +137,7 @@ TEST_F(BleConnectionManager, test_background_connection_multiple_clients) {
EXPECT_EQ(get_apps_connecting_to(address1).size(), 3UL);
- Mock::VerifyAndClearExpectations(test::mock_acl_manager_);
+ Mock::VerifyAndClearExpectations(test::mock_acl_manager_.get());
EXPECT_CALL(*test::mock_acl_manager_, CreateLeConnection(_, _)).Times(0);
@@ -153,7 +154,7 @@ TEST_F(BleConnectionManager, test_background_connection_multiple_clients) {
EXPECT_EQ(get_apps_connecting_to(address1).size(), 0UL);
- Mock::VerifyAndClearExpectations(test::mock_acl_manager_);
+ Mock::VerifyAndClearExpectations(test::mock_acl_manager_.get());
}
/** Verify adding/removing device to direct connection. */
@@ -173,7 +174,7 @@ TEST_F(BleConnectionManager, test_direct_connection_client) {
// Client that don't do direct connection should fail attempt to stop it
EXPECT_FALSE(direct_connect_remove(CLIENT2, address1));
- Mock::VerifyAndClearExpectations(test::mock_acl_manager_);
+ Mock::VerifyAndClearExpectations(test::mock_acl_manager_.get());
EXPECT_CALL(*test::mock_acl_manager_, CancelLeConnect(_)).Times(1);
EXPECT_CALL(*AlarmMock::Get(), AlarmFree(_)).Times(1);
@@ -183,7 +184,7 @@ TEST_F(BleConnectionManager, test_direct_connection_client) {
// acceptlist is in use, i.e. next connection attempt
EXPECT_TRUE(direct_connect_remove(CLIENT1, address1));
- Mock::VerifyAndClearExpectations(test::mock_acl_manager_);
+ Mock::VerifyAndClearExpectations(test::mock_acl_manager_.get());
}
/** Verify direct connection timeout does remove device from acceptlist, and
@@ -201,7 +202,7 @@ TEST_F(BleConnectionManager, test_direct_connect_timeout) {
// Start direct connect attempt...
EXPECT_TRUE(direct_connect_add(CLIENT1, address1));
- Mock::VerifyAndClearExpectations(test::mock_acl_manager_);
+ Mock::VerifyAndClearExpectations(test::mock_acl_manager_.get());
EXPECT_CALL(*test::mock_acl_manager_, CancelLeConnect(_)).Times(1);
EXPECT_CALL(*localConnTimeoutMock, OnConnectionTimedOut(CLIENT1, address1)).Times(1);
@@ -210,7 +211,7 @@ TEST_F(BleConnectionManager, test_direct_connect_timeout) {
// simulate timeout seconds passed, alarm executing
alarm_callback(alarm_data);
- Mock::VerifyAndClearExpectations(test::mock_acl_manager_);
+ Mock::VerifyAndClearExpectations(test::mock_acl_manager_.get());
}
/** Verify that we properly handle successfull direct connection */
@@ -222,7 +223,7 @@ TEST_F(BleConnectionManager, test_direct_connection_success) {
// Start direct connect attempt...
EXPECT_TRUE(direct_connect_add(CLIENT1, address1));
- Mock::VerifyAndClearExpectations(test::mock_acl_manager_);
+ Mock::VerifyAndClearExpectations(test::mock_acl_manager_.get());
EXPECT_CALL(*test::mock_acl_manager_, CancelLeConnect(address1_hci)).Times(1);
EXPECT_CALL(*AlarmMock::Get(), AlarmFree(_)).Times(1);
@@ -230,7 +231,7 @@ TEST_F(BleConnectionManager, test_direct_connection_success) {
// successfully.
on_connection_complete(address1);
- Mock::VerifyAndClearExpectations(test::mock_acl_manager_);
+ Mock::VerifyAndClearExpectations(test::mock_acl_manager_.get());
}
/** Verify that we properly handle application unregistration */
@@ -244,23 +245,23 @@ TEST_F(BleConnectionManager, test_app_unregister) {
EXPECT_CALL(*test::mock_acl_manager_, CreateLeConnection(address1_hci, true)).Times(1);
EXPECT_TRUE(direct_connect_add(CLIENT1, address1));
- Mock::VerifyAndClearExpectations(test::mock_acl_manager_);
+ Mock::VerifyAndClearExpectations(test::mock_acl_manager_.get());
EXPECT_CALL(*test::mock_acl_manager_, CreateLeConnection(address2_hci, false)).Times(1);
EXPECT_TRUE(background_connect_add(CLIENT1, address2));
- Mock::VerifyAndClearExpectations(test::mock_acl_manager_);
+ Mock::VerifyAndClearExpectations(test::mock_acl_manager_.get());
EXPECT_CALL(*test::mock_acl_manager_, CreateLeConnection(address2_hci, true)).Times(1);
EXPECT_TRUE(direct_connect_add(CLIENT2, address2));
- Mock::VerifyAndClearExpectations(test::mock_acl_manager_);
+ Mock::VerifyAndClearExpectations(test::mock_acl_manager_.get());
EXPECT_CALL(*test::mock_acl_manager_, CancelLeConnect(address1_hci)).Times(1);
on_app_deregistered(CLIENT1);
- Mock::VerifyAndClearExpectations(test::mock_acl_manager_);
+ Mock::VerifyAndClearExpectations(test::mock_acl_manager_.get());
EXPECT_CALL(*test::mock_acl_manager_, CancelLeConnect(address2_hci)).Times(1);
on_app_deregistered(CLIENT2);
- Mock::VerifyAndClearExpectations(test::mock_acl_manager_);
+ Mock::VerifyAndClearExpectations(test::mock_acl_manager_.get());
}
/** Verify adding device to both direct connection and background connection. */
@@ -273,7 +274,7 @@ TEST_F(BleConnectionManager, test_direct_and_background_connect) {
EXPECT_TRUE(direct_connect_add(CLIENT1, address1));
EXPECT_TRUE(background_connect_add(CLIENT1, address1));
- Mock::VerifyAndClearExpectations(test::mock_acl_manager_);
+ Mock::VerifyAndClearExpectations(test::mock_acl_manager_.get());
EXPECT_CALL(*AlarmMock::Get(), AlarmFree(_)).Times(1);
// not removing from acceptlist yet, as the background connection is still
@@ -284,7 +285,7 @@ TEST_F(BleConnectionManager, test_direct_and_background_connect) {
EXPECT_CALL(*test::mock_acl_manager_, CancelLeConnect(_)).Times(1);
EXPECT_TRUE(background_connect_remove(CLIENT1, address1));
- Mock::VerifyAndClearExpectations(test::mock_acl_manager_);
+ Mock::VerifyAndClearExpectations(test::mock_acl_manager_.get());
}
TEST_F(BleConnectionManager, test_target_announement_connect) {
@@ -302,7 +303,7 @@ TEST_F(BleConnectionManager, test_add_targeted_announement_when_allow_list_used)
EXPECT_TRUE(background_connect_add(CLIENT1, address1));
EXPECT_TRUE(background_connect_targeted_announcement_add(CLIENT2, address1));
- Mock::VerifyAndClearExpectations(test::mock_acl_manager_);
+ Mock::VerifyAndClearExpectations(test::mock_acl_manager_.get());
}
TEST_F(BleConnectionManager, test_add_background_connect_when_targeted_announcement_are_enabled) {
@@ -315,7 +316,7 @@ TEST_F(BleConnectionManager, test_add_background_connect_when_targeted_announcem
EXPECT_TRUE(background_connect_targeted_announcement_add(CLIENT2, address1));
EXPECT_TRUE(background_connect_add(CLIENT1, address1));
- Mock::VerifyAndClearExpectations(test::mock_acl_manager_);
+ Mock::VerifyAndClearExpectations(test::mock_acl_manager_.get());
}
TEST_F(BleConnectionManager, test_re_add_background_connect_to_allow_list) {
@@ -325,7 +326,7 @@ TEST_F(BleConnectionManager, test_re_add_background_connect_to_allow_list) {
EXPECT_TRUE(background_connect_targeted_announcement_add(CLIENT2, address1));
EXPECT_TRUE(background_connect_add(CLIENT1, address1));
- Mock::VerifyAndClearExpectations(test::mock_acl_manager_);
+ Mock::VerifyAndClearExpectations(test::mock_acl_manager_.get());
/* Now remove app using targeted announcement and expect device
* to be added to white list
@@ -335,11 +336,11 @@ TEST_F(BleConnectionManager, test_re_add_background_connect_to_allow_list) {
EXPECT_CALL(*test::mock_acl_manager_, CreateLeConnection(address1_hci, false)).Times(1);
EXPECT_TRUE(background_connect_remove(CLIENT2, address1));
- Mock::VerifyAndClearExpectations(test::mock_acl_manager_);
+ Mock::VerifyAndClearExpectations(test::mock_acl_manager_.get());
EXPECT_CALL(*test::mock_acl_manager_, CancelLeConnect(_)).Times(1);
EXPECT_TRUE(background_connect_remove(CLIENT1, address1));
- Mock::VerifyAndClearExpectations(test::mock_acl_manager_);
+ Mock::VerifyAndClearExpectations(test::mock_acl_manager_.get());
}
TEST_F(BleConnectionManager, test_re_add_to_allow_list_after_timeout_with_multiple_clients) {
@@ -352,7 +353,7 @@ TEST_F(BleConnectionManager, test_re_add_to_allow_list_after_timeout_with_multip
EXPECT_TRUE(background_connect_add(CLIENT1, address1));
- Mock::VerifyAndClearExpectations(test::mock_acl_manager_);
+ Mock::VerifyAndClearExpectations(test::mock_acl_manager_.get());
EXPECT_CALL(*AlarmMock::Get(), AlarmSetOnMloop(_, _, _, _))
.Times(1)
@@ -360,7 +361,7 @@ TEST_F(BleConnectionManager, test_re_add_to_allow_list_after_timeout_with_multip
// Start direct connect attempt...
EXPECT_TRUE(direct_connect_add(CLIENT2, address1));
- Mock::VerifyAndClearExpectations(test::mock_acl_manager_);
+ Mock::VerifyAndClearExpectations(test::mock_acl_manager_.get());
// simulate timeout seconds passed, alarm executing
EXPECT_CALL(*localConnTimeoutMock, OnConnectionTimedOut(CLIENT2, address1)).Times(1);
@@ -369,7 +370,7 @@ TEST_F(BleConnectionManager, test_re_add_to_allow_list_after_timeout_with_multip
EXPECT_CALL(*AlarmMock::Get(), AlarmFree(_)).Times(1);
alarm_callback(alarm_data);
- Mock::VerifyAndClearExpectations(test::mock_acl_manager_);
+ Mock::VerifyAndClearExpectations(test::mock_acl_manager_.get());
}
} // namespace connection_manager
diff --git a/system/stack/test/eatt/eatt_test.cc b/system/stack/test/eatt/eatt_test.cc
index 130893a0a5..5d7a2eeea8 100644
--- a/system/stack/test/eatt/eatt_test.cc
+++ b/system/stack/test/eatt/eatt_test.cc
@@ -219,11 +219,13 @@ protected:
le_buffer_size_.le_data_packet_length_ = 128;
le_buffer_size_.total_num_le_packets_ = 24;
- EXPECT_CALL(controller_, GetLeBufferSize).WillRepeatedly(Return(le_buffer_size_));
+ bluetooth::hci::testing::mock_controller_ =
+ std::make_unique<bluetooth::hci::testing::MockControllerInterface>();
+ EXPECT_CALL(*bluetooth::hci::testing::mock_controller_, GetLeBufferSize)
+ .WillRepeatedly(Return(le_buffer_size_));
bluetooth::l2cap::SetMockInterface(&l2cap_interface_);
bluetooth::manager::SetMockBtmApiInterface(&btm_api_interface_);
bluetooth::gatt::SetMockGattInterface(&gatt_interface_);
- bluetooth::hci::testing::mock_controller_ = &controller_;
// Clear the static memory for each test case
memset(&test_tcb, 0, sizeof(test_tcb));
@@ -258,7 +260,7 @@ protected:
bluetooth::l2cap::SetMockInterface(nullptr);
bluetooth::testing::stack::l2cap::reset_interface();
bluetooth::manager::SetMockBtmApiInterface(nullptr);
- bluetooth::hci::testing::mock_controller_ = nullptr;
+ bluetooth::hci::testing::mock_controller_.reset();
Test::TearDown();
}
@@ -269,7 +271,6 @@ protected:
bluetooth::l2cap::MockL2capInterface l2cap_interface_;
bluetooth::testing::stack::l2cap::Mock mock_stack_l2cap_interface_;
bluetooth::gatt::MockGattInterface gatt_interface_;
- bluetooth::hci::testing::MockControllerInterface controller_;
bluetooth::hci::LeBufferSize le_buffer_size_;
tL2CAP_APPL_INFO l2cap_app_info_;
diff --git a/system/stack/test/stack_acl_test.cc b/system/stack/test/stack_acl_test.cc
index b08a45cb80..bd0b153b9f 100644
--- a/system/stack/test/stack_acl_test.cc
+++ b/system/stack/test/stack_acl_test.cc
@@ -48,12 +48,12 @@ class StackAclTest : public testing::Test {
protected:
void SetUp() override {
reset_mock_function_count_map();
- bluetooth::hci::testing::mock_controller_ = &controller_;
+ bluetooth::hci::testing::mock_controller_ =
+ std::make_unique<bluetooth::hci::testing::MockControllerInterface>();
}
- void TearDown() override { bluetooth::hci::testing::mock_controller_ = nullptr; }
+ void TearDown() override { bluetooth::hci::testing::mock_controller_.reset(); }
tBTM_SEC_DEV_REC device_record_;
- bluetooth::hci::testing::MockControllerInterface controller_;
};
TEST_F(StackAclTest, nop) {}
diff --git a/system/stack/test/stack_l2cap_test.cc b/system/stack/test/stack_l2cap_test.cc
index ffe78055bc..204900b462 100644
--- a/system/stack/test/stack_l2cap_test.cc
+++ b/system/stack/test/stack_l2cap_test.cc
@@ -49,23 +49,23 @@ constexpr uint16_t kAclBufferSizeBle = 45;
class StackL2capTest : public ::testing::Test {
protected:
void SetUp() override {
- bluetooth::hci::testing::mock_controller_ = &controller_interface_;
- ON_CALL(controller_interface_, GetNumAclPacketBuffers)
+ bluetooth::hci::testing::mock_controller_ =
+ std::make_unique<bluetooth::hci::testing::MockControllerInterface>();
+ ON_CALL(*bluetooth::hci::testing::mock_controller_, GetNumAclPacketBuffers)
.WillByDefault(Return(kAclBufferCountClassic));
bluetooth::hci::LeBufferSize le_sizes;
le_sizes.total_num_le_packets_ = kAclBufferCountBle;
le_sizes.le_data_packet_length_ = kAclBufferSizeBle;
- ON_CALL(controller_interface_, GetLeBufferSize).WillByDefault(Return(le_sizes));
- ON_CALL(controller_interface_, SupportsBle).WillByDefault(Return(true));
+ ON_CALL(*bluetooth::hci::testing::mock_controller_, GetLeBufferSize)
+ .WillByDefault(Return(le_sizes));
+ ON_CALL(*bluetooth::hci::testing::mock_controller_, SupportsBle).WillByDefault(Return(true));
l2c_init();
}
void TearDown() override {
l2c_free();
- bluetooth::hci::testing::mock_controller_ = nullptr;
+ bluetooth::hci::testing::mock_controller_.reset();
}
-
- bluetooth::hci::testing::MockControllerInterface controller_interface_;
};
TEST_F(StackL2capTest, l2cble_process_data_length_change_event) {
diff --git a/system/test/Android.bp b/system/test/Android.bp
index c35931ea17..106dedb7bd 100644
--- a/system/test/Android.bp
+++ b/system/test/Android.bp
@@ -450,13 +450,6 @@ filegroup {
}
filegroup {
- name: "TestMockStackMetrics",
- srcs: [
- "mock/mock_stack_metrics*.cc",
- ],
-}
-
-filegroup {
name: "TestMockStackGap",
srcs: [
"mock/mock_stack_gap*.cc",
diff --git a/system/test/README.md b/system/test/README.md
deleted file mode 100644
index 1f43e952ef..0000000000
--- a/system/test/README.md
+++ /dev/null
@@ -1,81 +0,0 @@
-# Fluoride Bluetooth Tests
-
-This document refers to the tests in the packages/modules/Bluetooth/system/test directory.
-
-The tests are designed to be run when the Android runtime is not running. From a terminal, run:
-
-## Before you run tests
-```sh
-adb shell stop
-```
-
-## After you're done
-```sh
-adb shell start
-```
-
-## Running tests
-Then see what options the test script provides:
-
-```sh
-./run_unit_tests.sh --help
-```
-
-But for the impatient, run specific groups of tests like this:
-
-```sh
-./run_unit_tests.sh net_test_bluetooth
-```
-
-a single test:
-
-```sh
-./run_unit_tests.sh net_test_bluetooth.BluetoothTest.AdapterRepeatedEnableDisable
-```
-
-## Sample Output
-
-packages/modules/Bluetooth/system/test$ ./run_unit_tests.sh net_test_bluetooth
---- net_test_bluetooth ---
-pushing...
-/tbd/aosp-master/out/target/product/bullhead/data/nativetest/n...st_bluetooth: 1 file pushed. 9.2 MB/s (211832 bytes in 0.022s)
-running...
-
-Running main() from gtest_main.cc
-[==========] Running 11 tests from 2 test cases.
-[----------] Global test environment set-up.
-[----------] 6 tests from BluetoothTest
-[ RUN ] BluetoothTest.AdapterEnableDisable
-[ OK ] BluetoothTest.AdapterEnableDisable (2538 ms)
-[ RUN ] BluetoothTest.AdapterRepeatedEnableDisable
-[ OK ] BluetoothTest.AdapterRepeatedEnableDisable (11384 ms)
-[ RUN ] BluetoothTest.AdapterSetGetName
-[ OK ] BluetoothTest.AdapterSetGetName (2378 ms)
-[ RUN ] BluetoothTest.AdapterStartDiscovery
-[ OK ] BluetoothTest.AdapterStartDiscovery (2397 ms)
-[ RUN ] BluetoothTest.AdapterCancelDiscovery
-[ OK ] BluetoothTest.AdapterCancelDiscovery (2401 ms)
-[ RUN ] BluetoothTest.AdapterDisableDuringBonding
-[ OK ] BluetoothTest.AdapterDisableDuringBonding (11689 ms)
-[----------] 6 tests from BluetoothTest (32789 ms total)
-
-[----------] 5 tests from GattTest
-[ RUN ] GattTest.GattClientRegister
-[ OK ] GattTest.GattClientRegister (2370 ms)
-[ RUN ] GattTest.GattClientScanRemoteDevice
-[ OK ] GattTest.GattClientScanRemoteDevice (2273 ms)
-[ RUN ] GattTest.GattClientAdvertise
-[ OK ] GattTest.GattClientAdvertise (2236 ms)
-[ RUN ] GattTest.GattServerRegister
-[ OK ] GattTest.GattServerRegister (2391 ms)
-[ RUN ] GattTest.GattServerBuild
-[ OK ] GattTest.GattServerBuild (2435 ms)
-[----------] 5 tests from GattTest (11706 ms total)
-
-[----------] Global test environment tear-down
-[==========] 11 tests from 2 test cases ran. (44495 ms total)
-[ PASSED ] 11 tests.
-
-## Troubleshooting: Your phone is bricked!
-Probably not. See [After you're done](#After-you're-done)
-
diff --git a/system/test/mock/mock_main_shim_entry.cc b/system/test/mock/mock_main_shim_entry.cc
index 5d68f11b9d..3cdc714eaf 100644
--- a/system/test/mock/mock_main_shim_entry.cc
+++ b/system/test/mock/mock_main_shim_entry.cc
@@ -38,9 +38,9 @@ namespace bluetooth {
namespace hci {
namespace testing {
-MockAclManager* mock_acl_manager_{nullptr};
-MockControllerInterface* mock_controller_{nullptr};
-HciInterface* mock_hci_layer_{nullptr};
+std::unique_ptr<MockAclManager> mock_acl_manager_;
+std::unique_ptr<MockControllerInterface> mock_controller_;
+std::unique_ptr<MockHciLayer> mock_hci_layer_;
os::Handler* mock_gd_shim_handler_{nullptr};
MockLeAdvertisingManager* mock_le_advertising_manager_{nullptr};
MockLeScanningManager* mock_le_scanning_manager_{nullptr};
@@ -58,9 +58,9 @@ class Dumpsys;
namespace shim {
-hci::AclManager* GetAclManager() { return hci::testing::mock_acl_manager_; }
-hci::ControllerInterface* GetController() { return hci::testing::mock_controller_; }
-hci::HciInterface* GetHciLayer() { return hci::testing::mock_hci_layer_; }
+hci::AclManager* GetAclManager() { return hci::testing::mock_acl_manager_.get(); }
+hci::ControllerInterface* GetController() { return hci::testing::mock_controller_.get(); }
+hci::HciInterface* GetHciLayer() { return hci::testing::mock_hci_layer_.get(); }
hci::LeAdvertisingManager* GetAdvertising() { return hci::testing::mock_le_advertising_manager_; }
hci::LeScanningManager* GetScanning() { return hci::testing::mock_le_scanning_manager_; }
hci::DistanceMeasurementManager* GetDistanceMeasurementManager() {
diff --git a/system/test/mock/mock_main_shim_entry.h b/system/test/mock/mock_main_shim_entry.h
index ca84a27193..5d427fd963 100644
--- a/system/test/mock/mock_main_shim_entry.h
+++ b/system/test/mock/mock_main_shim_entry.h
@@ -15,11 +15,12 @@
*/
#include <functional>
+#include <memory>
#include "hci/acl_manager_mock.h"
#include "hci/controller_interface_mock.h"
#include "hci/distance_measurement_manager_mock.h"
-#include "hci/hci_interface.h"
+#include "hci/hci_layer_mock.h"
#include "hci/le_advertising_manager_mock.h"
#include "hci/le_scanning_manager_mock.h"
#include "storage/storage_module.h"
@@ -28,9 +29,9 @@ namespace bluetooth {
namespace hci {
namespace testing {
-extern MockAclManager* mock_acl_manager_;
-extern MockControllerInterface* mock_controller_;
-extern HciInterface* mock_hci_layer_;
+extern std::unique_ptr<MockAclManager> mock_acl_manager_;
+extern std::unique_ptr<MockControllerInterface> mock_controller_;
+extern std::unique_ptr<MockHciLayer> mock_hci_layer_;
extern os::Handler* mock_gd_shim_handler_;
extern MockLeAdvertisingManager* mock_le_advertising_manager_;
extern MockLeScanningManager* mock_le_scanning_manager_;
diff --git a/system/test/mock/mock_main_shim_metrics_api.cc b/system/test/mock/mock_main_shim_metrics_api.cc
index 0a501c7e6c..e635979ed8 100644
--- a/system/test/mock/mock_main_shim_metrics_api.cc
+++ b/system/test/mock/mock_main_shim_metrics_api.cc
@@ -184,12 +184,13 @@ void bluetooth::shim::LogMetricSdpAttribute(const RawAddress& raw_address, uint1
void bluetooth::shim::LogMetricSocketConnectionState(
const RawAddress& raw_address, int port, int type,
android::bluetooth::SocketConnectionstateEnum connection_state, int64_t tx_bytes,
- int64_t rx_bytes, int uid, int server_port,
- android::bluetooth::SocketRoleEnum socket_role) {
+ int64_t rx_bytes, int uid, int server_port, android::bluetooth::SocketRoleEnum socket_role,
+ uint64_t connection_duration_ms, android::bluetooth::SocketErrorEnum error_code,
+ bool is_hardware_offload) {
inc_func_call_count(__func__);
test::mock::main_shim_metrics_api::LogMetricSocketConnectionState(
raw_address, port, type, connection_state, tx_bytes, rx_bytes, uid, server_port,
- socket_role);
+ socket_role, connection_duration_ms, error_code, is_hardware_offload);
}
void bluetooth::shim::LogMetricManufacturerInfo(
const RawAddress& raw_address, android::bluetooth::AddressTypeEnum address_type,
diff --git a/system/test/mock/mock_main_shim_metrics_api.h b/system/test/mock/mock_main_shim_metrics_api.h
index 887090d743..4beaab72c0 100644
--- a/system/test/mock/mock_main_shim_metrics_api.h
+++ b/system/test/mock/mock_main_shim_metrics_api.h
@@ -274,17 +274,23 @@ struct LogMetricSocketConnectionState {
std::function<void(const RawAddress& raw_address, int port, int type,
android::bluetooth::SocketConnectionstateEnum connection_state,
int64_t tx_bytes, int64_t rx_bytes, int uid, int server_port,
- android::bluetooth::SocketRoleEnum socket_role)>
+ android::bluetooth::SocketRoleEnum socket_role,
+ uint64_t connection_duration_ms,
+ android::bluetooth::SocketErrorEnum error_code, bool is_hardware_offload)>
body{[](const RawAddress& /* raw_address */, int /* port */, int /* type */,
android::bluetooth::SocketConnectionstateEnum /* connection_state */,
int64_t /* tx_bytes */, int64_t /* rx_bytes */, int /* uid */,
- int /* server_port */, android::bluetooth::SocketRoleEnum /* socket_role */) {}};
+ int /* server_port */, android::bluetooth::SocketRoleEnum /* socket_role */,
+ uint64_t /* connection_duration_ms */,
+ android::bluetooth::SocketErrorEnum /* error_code */,
+ bool /* is_hardware_offload */) {}};
void operator()(const RawAddress& raw_address, int port, int type,
android::bluetooth::SocketConnectionstateEnum connection_state, int64_t tx_bytes,
int64_t rx_bytes, int uid, int server_port,
- android::bluetooth::SocketRoleEnum socket_role) {
+ android::bluetooth::SocketRoleEnum socket_role, uint64_t connection_duration_ms,
+ android::bluetooth::SocketErrorEnum error_code, bool is_hardware_offload) {
body(raw_address, port, type, connection_state, tx_bytes, rx_bytes, uid, server_port,
- socket_role);
+ socket_role, connection_duration_ms, error_code, is_hardware_offload);
}
};
extern struct LogMetricSocketConnectionState LogMetricSocketConnectionState;
diff --git a/system/test/mock/mock_stack_metrics_logging.cc b/system/test/mock/mock_stack_metrics_logging.cc
deleted file mode 100644
index ff2cee4472..0000000000
--- a/system/test/mock/mock_stack_metrics_logging.cc
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Copyright 2021 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.
- */
-
-/*
- * Generated mock file from original source file
- * Functions generated:5
- *
- * mockcify.pl ver 0.2
- */
-// Mock include file to share data between tests and mock
-#include "test/mock/mock_stack_metrics_logging.h"
-
-#include <string>
-
-// Original included files, if any
-#include <frameworks/proto_logging/stats/enums/bluetooth/enums.pb.h>
-#include <frameworks/proto_logging/stats/enums/bluetooth/hci/enums.pb.h>
-
-#include "stack/include/stack_metrics_logging.h"
-#include "test/common/mock_functions.h"
-#include "types/raw_address.h"
-
-// Mocked compile conditionals, if any
-// Mocked internal structures, if any
-
-namespace test {
-namespace mock {
-namespace stack_metrics_logging {
-
-// Function state capture and return values, if needed
-struct log_classic_pairing_event log_classic_pairing_event;
-struct log_link_layer_connection_event log_link_layer_connection_event;
-struct log_smp_pairing_event log_smp_pairing_event;
-struct log_le_pairing_fail log_le_pairing_fail;
-struct log_sdp_attribute log_sdp_attribute;
-struct log_manufacturer_info log_manufacturer_info;
-struct log_counter_metrics log_counter_metrics;
-struct log_hfp_audio_packet_loss_stats log_hfp_audio_packet_loss_stats;
-struct log_mmc_transcode_rtt_stats log_mmc_transcode_rtt_stats;
-struct log_le_connection_status log_le_connection_status;
-struct log_le_device_in_accept_list log_le_device_in_accept_list;
-struct log_le_connection_lifecycle log_le_connection_lifecycle;
-struct log_le_connection_completion log_le_connection_completion;
-
-} // namespace stack_metrics_logging
-} // namespace mock
-} // namespace test
-
-// Mocked functions, if any
-void log_classic_pairing_event(const RawAddress& address, uint16_t handle, uint32_t hci_cmd,
- uint16_t hci_event, uint16_t cmd_status, uint16_t reason_code,
- int64_t event_value) {
- inc_func_call_count(__func__);
- test::mock::stack_metrics_logging::log_classic_pairing_event(
- address, handle, hci_cmd, hci_event, cmd_status, reason_code, event_value);
-}
-void log_link_layer_connection_event(const RawAddress* address, uint32_t connection_handle,
- android::bluetooth::DirectionEnum direction,
- uint16_t link_type, uint32_t hci_cmd, uint16_t hci_event,
- uint16_t hci_ble_event, uint16_t cmd_status,
- uint16_t reason_code) {
- inc_func_call_count(__func__);
- test::mock::stack_metrics_logging::log_link_layer_connection_event(
- address, connection_handle, direction, link_type, hci_cmd, hci_event, hci_ble_event,
- cmd_status, reason_code);
-}
-void log_smp_pairing_event(const RawAddress& address, uint16_t smp_cmd,
- android::bluetooth::DirectionEnum direction, uint16_t smp_fail_reason) {
- inc_func_call_count(__func__);
- test::mock::stack_metrics_logging::log_smp_pairing_event(address, smp_cmd, direction,
- smp_fail_reason);
-}
-
-void log_le_pairing_fail(const RawAddress& raw_address, uint8_t failure_reason, bool is_outgoing) {
- inc_func_call_count(__func__);
- test::mock::stack_metrics_logging::log_le_pairing_fail(raw_address, failure_reason, is_outgoing);
-}
-
-void log_sdp_attribute(const RawAddress& address, uint16_t protocol_uuid, uint16_t attribute_id,
- size_t attribute_size, const char* attribute_value) {
- inc_func_call_count(__func__);
- test::mock::stack_metrics_logging::log_sdp_attribute(address, protocol_uuid, attribute_id,
- attribute_size, attribute_value);
-}
-void log_manufacturer_info(const RawAddress& address,
- android::bluetooth::AddressTypeEnum address_type,
- android::bluetooth::DeviceInfoSrcEnum source_type,
- const std::string& source_name, const std::string& manufacturer,
- const std::string& model, const std::string& hardware_version,
- const std::string& software_version) {
- inc_func_call_count(__func__);
- test::mock::stack_metrics_logging::log_manufacturer_info(address, address_type, source_type,
- source_name, manufacturer, model,
- hardware_version, software_version);
-}
-
-void log_counter_metrics(android::bluetooth::CodePathCounterKeyEnum key, int64_t value) {
- inc_func_call_count(__func__);
- test::mock::stack_metrics_logging::log_counter_metrics(key, value);
-}
-
-void log_hfp_audio_packet_loss_stats(const RawAddress& address, int num_decoded_frames,
- double packet_loss_ratio, uint16_t codec_type) {
- inc_func_call_count(__func__);
- test::mock::stack_metrics_logging::log_hfp_audio_packet_loss_stats(address, num_decoded_frames,
- packet_loss_ratio, codec_type);
-}
-
-void log_mmc_transcode_rtt_stats(int maximum_rtt, double mean_rtt, int num_requests,
- int codec_type) {
- inc_func_call_count(__func__);
- test::mock::stack_metrics_logging::log_mmc_transcode_rtt_stats(maximum_rtt, mean_rtt,
- num_requests, codec_type);
-}
-
-void log_le_connection_status(bluetooth::hci::Address address, bool is_connect,
- bluetooth::hci::ErrorCode reason) {
- inc_func_call_count(__func__);
- test::mock::stack_metrics_logging::log_le_connection_status(address, is_connect, reason);
-}
-
-void log_le_device_in_accept_list(bluetooth::hci::Address address, bool is_add) {
- inc_func_call_count(__func__);
- test::mock::stack_metrics_logging::log_le_device_in_accept_list(address, is_add);
-}
-
-void log_le_connection_lifecycle(bluetooth::hci::Address address, bool is_connect, bool is_direct) {
- inc_func_call_count(__func__);
- test::mock::stack_metrics_logging::log_le_connection_lifecycle(address, is_connect, is_direct);
-}
-
-void log_le_connection_completion(bluetooth::hci::Address address, bluetooth::hci::ErrorCode reason,
- bool is_locally_initiated) {
- inc_func_call_count(__func__);
- test::mock::stack_metrics_logging::log_le_connection_completion(address, reason,
- is_locally_initiated);
-}
-// END mockcify generation
diff --git a/system/test/mock/mock_stack_metrics_logging.h b/system/test/mock/mock_stack_metrics_logging.h
deleted file mode 100644
index 40212e60ea..0000000000
--- a/system/test/mock/mock_stack_metrics_logging.h
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * Copyright 2021 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.
- */
-
-/*
- * Generated mock file from original source file
- * Functions generated:5
- *
- * mockcify.pl ver 0.2
- */
-
-#include <string>
-
-// Original included files, if any
-#include <frameworks/proto_logging/stats/enums/bluetooth/enums.pb.h>
-#include <frameworks/proto_logging/stats/enums/bluetooth/hci/enums.pb.h>
-
-#include "hci/address.h"
-#include "hci/hci_packets.h"
-#include "types/raw_address.h"
-
-// Mocked compile conditionals, if any
-
-namespace test {
-namespace mock {
-namespace stack_metrics_logging {
-
-// Shared state between mocked functions and tests
-// Name: log_classic_pairing_event
-// Params: const RawAddress& address, uint16_t handle, uint32_t hci_cmd,
-// uint16_t hci_event, uint16_t cmd_status, uint16_t reason_code, int64_t
-// event_value Returns: void
-struct log_classic_pairing_event {
- std::function<void(const RawAddress& address, uint16_t handle, uint32_t hci_cmd,
- uint16_t hci_event, uint16_t cmd_status, uint16_t reason_code,
- int64_t event_value)>
- body{[](const RawAddress& /* address */, uint16_t /* handle */, uint32_t /* hci_cmd */,
- uint16_t /* hci_event */, uint16_t /* cmd_status */, uint16_t /* reason_code */,
- int64_t /* event_value */) {}};
- void operator()(const RawAddress& address, uint16_t handle, uint32_t hci_cmd, uint16_t hci_event,
- uint16_t cmd_status, uint16_t reason_code, int64_t event_value) {
- body(address, handle, hci_cmd, hci_event, cmd_status, reason_code, event_value);
- }
-};
-extern struct log_classic_pairing_event log_classic_pairing_event;
-// Name: log_link_layer_connection_event
-// Params: const RawAddress* address, uint32_t connection_handle,
-// android::bluetooth::DirectionEnum direction, uint16_t link_type, uint32_t
-// hci_cmd, uint16_t hci_event, uint16_t hci_ble_event, uint16_t cmd_status,
-// uint16_t reason_code Returns: void
-struct log_link_layer_connection_event {
- std::function<void(const RawAddress* address, uint32_t connection_handle,
- android::bluetooth::DirectionEnum direction, uint16_t link_type,
- uint32_t hci_cmd, uint16_t hci_event, uint16_t hci_ble_event,
- uint16_t cmd_status, uint16_t reason_code)>
- body{[](const RawAddress* /* address */, uint32_t /* connection_handle */,
- android::bluetooth::DirectionEnum /* direction */, uint16_t /* link_type */,
- uint32_t /* hci_cmd */, uint16_t /* hci_event */, uint16_t /* hci_ble_event */,
- uint16_t /* cmd_status */, uint16_t /* reason_code */) {}};
- void operator()(const RawAddress* address, uint32_t connection_handle,
- android::bluetooth::DirectionEnum direction, uint16_t link_type, uint32_t hci_cmd,
- uint16_t hci_event, uint16_t hci_ble_event, uint16_t cmd_status,
- uint16_t reason_code) {
- body(address, connection_handle, direction, link_type, hci_cmd, hci_event, hci_ble_event,
- cmd_status, reason_code);
- }
-};
-extern struct log_link_layer_connection_event log_link_layer_connection_event;
-// Name: log_smp_pairing_event
-// Params: const RawAddress& address, uint16_t smp_cmd,
-// android::bluetooth::DirectionEnum direction, uint8_t smp_fail_reason Returns:
-// void
-struct log_smp_pairing_event {
- std::function<void(const RawAddress& address, uint16_t smp_cmd,
- android::bluetooth::DirectionEnum direction, uint16_t smp_fail_reason)>
- body{[](const RawAddress& /* address */, uint16_t /* smp_cmd */,
- android::bluetooth::DirectionEnum /* direction */,
- uint16_t /* smp_fail_reason */) {}};
- void operator()(const RawAddress& address, uint16_t smp_cmd,
- android::bluetooth::DirectionEnum direction, uint16_t smp_fail_reason) {
- body(address, smp_cmd, direction, smp_fail_reason);
- }
-};
-extern struct log_smp_pairing_event log_smp_pairing_event;
-
-// Name: log_le_pairing_fail
-// Params: const RawAddress& raw_address, uint8_t failure_reason, bool
-// is_outgoing Returns:
-// void
-// Name: log_sdp_attribute
-// Params: const RawAddress& address, uint16_t protocol_uuid, uint16_t
-// attribute_id, size_t attribute_size, const char* attribute_value Returns:
-// void
-struct log_le_pairing_fail {
- std::function<void(const RawAddress& raw_address, uint8_t failure_reason, bool is_outgoing)> body{
- [](const RawAddress& /* address */, uint8_t /* failure reason */,
- bool /* is_outgoing */) {}};
- void operator()(const RawAddress& raw_address, uint8_t failure_reason, bool is_outgoing) {
- body(raw_address, failure_reason, is_outgoing);
- }
-};
-extern struct log_le_pairing_fail log_le_pairing_fail;
-
-struct log_sdp_attribute {
- std::function<void(const RawAddress& address, uint16_t protocol_uuid, uint16_t attribute_id,
- size_t attribute_size, const char* attribute_value)>
- body{[](const RawAddress& /* address */, uint16_t /* protocol_uuid */,
- uint16_t /* attribute_id */, size_t /* attribute_size */,
- const char* /* attribute_value */) {}};
- void operator()(const RawAddress& address, uint16_t protocol_uuid, uint16_t attribute_id,
- size_t attribute_size, const char* attribute_value) {
- body(address, protocol_uuid, attribute_id, attribute_size, attribute_value);
- }
-};
-extern struct log_sdp_attribute log_sdp_attribute;
-// Name: log_manufacturer_info
-// Params: const RawAddress& address, android::bluetooth::DeviceInfoSrcEnum
-// source_type, const std::string& source_name, const std::string& manufacturer,
-// const std::string& model, const std::string& hardware_version, const
-// std::string& software_version Returns: void
-struct log_manufacturer_info {
- std::function<void(const RawAddress& address, android::bluetooth::AddressTypeEnum address_type,
- android::bluetooth::DeviceInfoSrcEnum source_type,
- const std::string& source_name, const std::string& manufacturer,
- const std::string& model, const std::string& hardware_version,
- const std::string& software_version)>
- body2{[](const RawAddress& /* address */,
- android::bluetooth::AddressTypeEnum /* address_type */,
- android::bluetooth::DeviceInfoSrcEnum /* source_type */,
- const std::string& /* source_name */, const std::string& /* manufacturer */,
- const std::string& /* model */, const std::string& /* hardware_version */,
- const std::string& /* software_version */) {}};
- void operator()(const RawAddress& address, android::bluetooth::AddressTypeEnum address_type,
- android::bluetooth::DeviceInfoSrcEnum source_type, const std::string& source_name,
- const std::string& manufacturer, const std::string& model,
- const std::string& hardware_version, const std::string& software_version) {
- body2(address, address_type, source_type, source_name, manufacturer, model, hardware_version,
- software_version);
- }
- std::function<void(const RawAddress& address, android::bluetooth::DeviceInfoSrcEnum source_type,
- const std::string& source_name, const std::string& manufacturer,
- const std::string& model, const std::string& hardware_version,
- const std::string& software_version)>
- body{[](const RawAddress& /* address */,
- android::bluetooth::DeviceInfoSrcEnum /* source_type */,
- const std::string& /* source_name */, const std::string& /* manufacturer */,
- const std::string& /* model */, const std::string& /* hardware_version */,
- const std::string& /* software_version */) {}};
- void operator()(const RawAddress& address, android::bluetooth::DeviceInfoSrcEnum source_type,
- const std::string& source_name, const std::string& manufacturer,
- const std::string& model, const std::string& hardware_version,
- const std::string& software_version) {
- body(address, source_type, source_name, manufacturer, model, hardware_version,
- software_version);
- }
-};
-extern struct log_manufacturer_info log_manufacturer_info;
-
-// Name: log_counter_metrics
-struct log_counter_metrics {
- std::function<void(android::bluetooth::CodePathCounterKeyEnum key, int64_t value)> body{
- [](android::bluetooth::CodePathCounterKeyEnum /* key */, int64_t /* value */) {}};
- void operator()(android::bluetooth::CodePathCounterKeyEnum key, int64_t value) {
- body(key, value);
- }
-};
-extern struct log_counter_metrics log_counter_metrics;
-
-// Name: log_hfp_audio_packet_loss_stats
-struct log_hfp_audio_packet_loss_stats {
- std::function<void(const RawAddress& address, int num_decoded_frames, double packet_loss_ratio,
- uint16_t codec_type)>
- body{[](const RawAddress& /* address */, int /* num_decoded_frames */,
- double /* packet_loss_ratio */, uint16_t /* codec_type */) {}};
- void operator()(const RawAddress& address, int num_decoded_frames, double packet_loss_ratio,
- uint16_t codec_type) {
- body(address, num_decoded_frames, packet_loss_ratio, codec_type);
- }
-};
-extern struct log_hfp_audio_packet_loss_stats log_hfp_audio_packet_loss_stats;
-
-// Name: log_mmc_transcode_rtt_stats
-struct log_mmc_transcode_rtt_stats {
- std::function<void(int maximum_rtt, double mean_rtt, int num_requests, int codec_type)> body{
- [](int /* maximum_rtt */, double /* mean_rtt */, int /* num_requests */,
- int /* codec_type */) {}};
- void operator()(int maximum_rtt, double mean_rtt, int num_requests, int codec_type) {
- body(maximum_rtt, mean_rtt, num_requests, codec_type);
- }
-};
-extern struct log_mmc_transcode_rtt_stats log_mmc_transcode_rtt_stats;
-
-// Name: log_le_connection_status
-struct log_le_connection_status {
- std::function<void(bluetooth::hci::Address address, bool is_connect,
- bluetooth::hci::ErrorCode reason)>
- body{[](bluetooth::hci::Address /* address */, bool /* is_connect */,
- bluetooth::hci::ErrorCode /* reason */) {}};
- void operator()(bluetooth::hci::Address address, bool is_connect,
- bluetooth::hci::ErrorCode reason) {
- body(address, is_connect, reason);
- }
-};
-extern struct log_le_connection_status log_le_connection_status;
-
-// Name: log_le_device_in_accept_list
-struct log_le_device_in_accept_list {
- std::function<void(bluetooth::hci::Address address, bool is_add)> body{
- [](bluetooth::hci::Address /* address */, bool /* is_add */) {}};
- void operator()(bluetooth::hci::Address address, bool is_add) { body(address, is_add); }
-};
-extern struct log_le_device_in_accept_list log_le_device_in_accept_list;
-
-// Name: log_le_connection_lifecycle
-struct log_le_connection_lifecycle {
- std::function<void(bluetooth::hci::Address address, bool is_connect, bool is_direct)> body{
- [](bluetooth::hci::Address /* address */, bool /* is_connect */, bool /* is_direct */) {
- }};
- void operator()(bluetooth::hci::Address address, bool is_connect, bool is_direct) {
- body(address, is_connect, is_direct);
- }
-};
-extern struct log_le_device_in_accept_list log_le_device_in_accept_list;
-
-// Name: log_le_connection_completion
-struct log_le_connection_completion {
- std::function<void(bluetooth::hci::Address address, bluetooth::hci::ErrorCode reason,
- bool is_locally_initiated)>
- body{[](bluetooth::hci::Address /* address */, bluetooth::hci::ErrorCode /* reason */,
- bool /* is locally initiated */) {}};
- void operator()(bluetooth::hci::Address address, bluetooth::hci::ErrorCode reason,
- bool is_locally_initiated) {
- body(address, reason, is_locally_initiated);
- }
-};
-extern struct log_le_connection_completion log_le_connection_completion;
-
-} // namespace stack_metrics_logging
-} // namespace mock
-} // namespace test
-
-// END mockcify generation