diff options
4 files changed, 156 insertions, 194 deletions
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 07ff67b65b..82b8e10dd7 100644 --- a/android/app/src/com/android/bluetooth/le_scan/ScanController.java +++ b/android/app/src/com/android/bluetooth/le_scan/ScanController.java @@ -72,11 +72,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; @@ -137,7 +135,6 @@ public class ScanController { private volatile boolean mTestModeEnabled = false; private ScannerMap mScannerMap = new ScannerMap(); - private boolean mIsAvailable; private Handler mTestModeHandler; public ScanController(AdapterService adapterService) { @@ -165,7 +162,6 @@ public class ScanController { }; mMainLooper = adapterService.getMainLooper(); mBinder = new ScanBinder(this); - mIsAvailable = true; mScanThread = new HandlerThread("BluetoothScanManager"); mScanThread.start(); mAppOps = mAdapterService.getSystemService(AppOpsManager.class); @@ -182,18 +178,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; } diff --git a/android/app/tests/unit/src/com/android/bluetooth/le_scan/ScanBinderTest.java b/android/app/tests/unit/src/com/android/bluetooth/le_scan/ScanBinderTest.java index 7687fb381d..61c7df48b8 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/le_scan/ScanBinderTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/le_scan/ScanBinderTest.java @@ -21,7 +21,6 @@ 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.app.PendingIntent; import android.bluetooth.BluetoothDevice; @@ -67,7 +66,6 @@ public class ScanBinderTest { @Before public void setUp() { - when(mScanController.isAvailable()).thenReturn(true); mBinder = new ScanBinder(mScanController); } @@ -188,4 +186,9 @@ public class ScanBinderTest { mBinder.numHwTrackFiltersAvailable(mAttributionSource); verify(mScanController).numHwTrackFiltersAvailable(mAttributionSource); } + + @Test + public void cleanup_doesNotCrash() { + mBinder.cleanup(); + } } |