Loading android/app/src/com/android/bluetooth/gatt/ContextMap.java +9 −9 Original line number Diff line number Diff line Loading @@ -211,7 +211,7 @@ public class ContextMap<C, T> { private final Object mConnectionsLock = new Object(); /** Add an entry to the application context list. */ App add( protected App add( UUID uuid, WorkSource workSource, C callback, Loading Loading @@ -292,7 +292,7 @@ public class ContextMap<C, T> { /** * Remove the context for a given application ID. */ void remove(int id) { protected void remove(int id) { boolean find = false; synchronized (mAppsLock) { Iterator<App> i = mApps.iterator(); Loading @@ -312,7 +312,7 @@ public class ContextMap<C, T> { } } List<Integer> getAllAppsIds() { protected List<Integer> getAllAppsIds() { List<Integer> appIds = new ArrayList(); synchronized (mAppsLock) { Iterator<App> i = mApps.iterator(); Loading Loading @@ -370,7 +370,7 @@ public class ContextMap<C, T> { /** * Get an application context by ID. */ App getById(int id) { protected App getById(int id) { synchronized (mAppsLock) { Iterator<App> i = mApps.iterator(); while (i.hasNext()) { Loading @@ -387,7 +387,7 @@ public class ContextMap<C, T> { /** * Get an application context by UUID. */ App getByUuid(UUID uuid) { protected App getByUuid(UUID uuid) { synchronized (mAppsLock) { Iterator<App> i = mApps.iterator(); while (i.hasNext()) { Loading Loading @@ -421,7 +421,7 @@ public class ContextMap<C, T> { /** * Get an application context by the context info object. */ App getByContextInfo(T contextInfo) { protected App getByContextInfo(T contextInfo) { synchronized (mAppsLock) { Iterator<App> i = mApps.iterator(); while (i.hasNext()) { Loading @@ -438,7 +438,7 @@ public class ContextMap<C, T> { /** * Get Logging info by ID */ AppScanStats getAppScanStatsById(int id) { protected AppScanStats getAppScanStatsById(int id) { App temp = getById(id); if (temp != null) { return temp.appScanStats; Loading Loading @@ -674,7 +674,7 @@ public class ContextMap<C, T> { /** * Erases all application context entries. */ void clear() { protected void clear() { synchronized (mAppsLock) { Iterator<App> i = mApps.iterator(); while (i.hasNext()) { Loading Loading @@ -713,7 +713,7 @@ public class ContextMap<C, T> { /** * Logs debug information. */ void dump(StringBuilder sb) { protected void dump(StringBuilder sb) { sb.append(" Entries: " + mAppScanStats.size() + "\n\n"); Iterator<Map.Entry<Integer, AppScanStats>> it = mAppScanStats.entrySet().iterator(); Loading android/app/src/com/android/bluetooth/gatt/GattService.java +43 −33 Original line number Diff line number Diff line Loading @@ -100,6 +100,7 @@ import com.android.bluetooth.le_scan.AppScanStats; import com.android.bluetooth.le_scan.PeriodicScanManager; import com.android.bluetooth.le_scan.ScanClient; import com.android.bluetooth.le_scan.ScanManager; import com.android.bluetooth.le_scan.TransitionalScanHelper; import com.android.bluetooth.util.NumberUtils; import com.android.internal.annotations.VisibleForTesting; import com.android.modules.utils.SynchronousResultReceiver; Loading Loading @@ -213,7 +214,7 @@ public class GattService extends ProfileService { /** * Keep the arguments passed in for the PendingIntent. */ class PendingIntentInfo { public static class PendingIntentInfo { public PendingIntent intent; public ScanSettings settings; public List<ScanFilter> filters; Loading @@ -237,12 +238,7 @@ public class GattService extends ProfileService { } }; /** * List of our registered scanners. */ public static class ScannerMap extends ContextMap<IScannerCallback, PendingIntentInfo> {} public ScannerMap mScannerMap = new ScannerMap(); public final TransitionalScanHelper mTransitionalScanHelper = new TransitionalScanHelper(); /** * List of our registered advertisers. Loading Loading @@ -394,7 +390,7 @@ public class GattService extends ProfileService { if (DBG) { Log.d(TAG, "stop()"); } mScannerMap.clear(); mTransitionalScanHelper.getScannerMap().clear(); mAdvertiserMap.clear(); mClientMap.clear(); if (Flags.gattCleanupRestrictedHandles()) { Loading Loading @@ -2020,7 +2016,8 @@ public class GattService extends ProfileService { byte[] legacyAdvData = Arrays.copyOfRange(advData, 0, 62); for (ScanClient client : mScanManager.getRegularScanQueue()) { ScannerMap.App app = mScannerMap.getById(client.scannerId); TransitionalScanHelper.ScannerMap.App app = mTransitionalScanHelper.getScannerMap().getById(client.scannerId); if (app == null) { if (VDBG) { Log.d(TAG, "App is null; skip."); Loading Loading @@ -2112,7 +2109,7 @@ public class GattService extends ProfileService { if (Flags.leScanFixRemoteException()) { handleDeadScanClient(client); } else { mScannerMap.remove(client.scannerId); mTransitionalScanHelper.getScannerMap().remove(client.scannerId); mScanManager.stopScan(client.scannerId); } } Loading Loading @@ -2161,7 +2158,8 @@ public class GattService extends ProfileService { } // First check the callback map ScannerMap.App cbApp = mScannerMap.getByUuid(uuid); TransitionalScanHelper.ScannerMap.App cbApp = mTransitionalScanHelper.getScannerMap().getByUuid(uuid); if (cbApp != null) { if (status == 0) { cbApp.id = scannerId; Loading @@ -2173,7 +2171,7 @@ public class GattService extends ProfileService { continuePiStartScan(scannerId, cbApp); } } else { mScannerMap.remove(scannerId); mTransitionalScanHelper.getScannerMap().remove(scannerId); } if (cbApp.callback != null) { cbApp.callback.onScannerRegistered(status, scannerId); Loading Loading @@ -2802,7 +2800,8 @@ public class GattService extends ProfileService { Set<ScanResult> results = parseBatchScanResults(numRecords, reportType, recordData); if (reportType == ScanManager.SCAN_RESULT_TYPE_TRUNCATED) { // We only support single client for truncated mode. ScannerMap.App app = mScannerMap.getById(scannerId); TransitionalScanHelper.ScannerMap.App app = mTransitionalScanHelper.getScannerMap().getById(scannerId); if (app == null) { return; } Loading Loading @@ -2853,7 +2852,7 @@ public class GattService extends ProfileService { mScanManager.callbackDone(scannerId, status); } private void sendBatchScanResults(ScannerMap.App app, ScanClient client, private void sendBatchScanResults(TransitionalScanHelper.ScannerMap.App app, ScanClient client, ArrayList<ScanResult> results) { try { if (app.callback != null) { Loading @@ -2880,7 +2879,7 @@ public class GattService extends ProfileService { if (Flags.leScanFixRemoteException()) { handleDeadScanClient(client); } else { mScannerMap.remove(client.scannerId); mTransitionalScanHelper.getScannerMap().remove(client.scannerId); mScanManager.stopScan(client.scannerId); } } Loading @@ -2889,7 +2888,8 @@ public class GattService extends ProfileService { // Check and deliver scan results for different scan clients. private void deliverBatchScan(ScanClient client, Set<ScanResult> allResults) throws RemoteException { ScannerMap.App app = mScannerMap.getById(client.scannerId); TransitionalScanHelper.ScannerMap.App app = mTransitionalScanHelper.getScannerMap().getById(client.scannerId); if (app == null) { return; } Loading Loading @@ -3050,7 +3050,8 @@ public class GattService extends ProfileService { + trackingInfo.getAdvState()); } ScannerMap.App app = mScannerMap.getById(trackingInfo.getClientIf()); TransitionalScanHelper.ScannerMap.App app = mTransitionalScanHelper.getScannerMap().getById(trackingInfo.getClientIf()); if (app == null || (app.callback == null && app.info == null)) { Log.e(TAG, "app or callback is null"); return; Loading Loading @@ -3096,7 +3097,8 @@ public class GattService extends ProfileService { } void onScanParamSetupCompleted(int status, int scannerId) throws RemoteException { ScannerMap.App app = mScannerMap.getById(scannerId); TransitionalScanHelper.ScannerMap.App app = mTransitionalScanHelper.getScannerMap().getById(scannerId); if (app == null || app.callback == null) { Log.e(TAG, "Advertise app or callback is null"); return; Loading @@ -3108,7 +3110,8 @@ public class GattService extends ProfileService { // callback from ScanManager for dispatch of errors apps. public void onScanManagerErrorCallback(int scannerId, int errorCode) throws RemoteException { ScannerMap.App app = mScannerMap.getById(scannerId); TransitionalScanHelper.ScannerMap.App app = mTransitionalScanHelper.getScannerMap().getById(scannerId); if (app == null || (app.callback == null && app.info == null)) { Log.e(TAG, "App or callback is null"); return; Loading Loading @@ -3225,7 +3228,8 @@ public class GattService extends ProfileService { enforceImpersonatationPermissionIfNeeded(workSource); AppScanStats app = mScannerMap.getAppScanStatsByUid(Binder.getCallingUid()); AppScanStats app = mTransitionalScanHelper.getScannerMap() .getAppScanStatsByUid(Binder.getCallingUid()); if (app != null && app.isScanningTooFrequently() && !Utils.checkCallerHasPrivilegedPermission(this)) { Log.e(TAG, "App '" + app.appName + "' is scanning too frequently"); Loading @@ -3233,7 +3237,8 @@ public class GattService extends ProfileService { return; } mScannerMap.add(uuid, workSource, callback, null, this); mTransitionalScanHelper .getScannerMap().add(uuid, workSource, callback, null, this); mScanManager.registerScanner(uuid); } Loading @@ -3247,7 +3252,7 @@ public class GattService extends ProfileService { if (DBG) { Log.d(TAG, "unregisterScanner() - scannerId=" + scannerId); } mScannerMap.remove(scannerId); mTransitionalScanHelper.getScannerMap().remove(scannerId); mScanManager.unregisterScanner(scannerId); } Loading Loading @@ -3319,8 +3324,9 @@ public class GattService extends ProfileService { Utils.checkCallerHasScanWithoutLocationPermission(this); scanClient.associatedDevices = getAssociatedDevices(callingPackage); AppScanStats app = mScannerMap.getAppScanStatsById(scannerId); ScannerMap.App cbApp = mScannerMap.getById(scannerId); AppScanStats app = mTransitionalScanHelper.getScannerMap().getAppScanStatsById(scannerId); TransitionalScanHelper.ScannerMap.App cbApp = mTransitionalScanHelper.getScannerMap().getById(scannerId); if (app != null) { scanClient.stats = app; boolean isFilteredScan = (filters != null) && !filters.isEmpty(); Loading Loading @@ -3367,12 +3373,13 @@ public class GattService extends ProfileService { } // Don't start scan if the Pi scan already in mScannerMap. if (mScannerMap.getByContextInfo(piInfo) != null) { if (mTransitionalScanHelper.getScannerMap().getByContextInfo(piInfo) != null) { Log.d(TAG, "Don't startScan(PI) since the same Pi scan already in mScannerMap."); return; } ScannerMap.App app = mScannerMap.add(uuid, null, null, piInfo, this); TransitionalScanHelper.ScannerMap.App app = mTransitionalScanHelper.getScannerMap().add(uuid, null, null, piInfo, this); app.mUserHandle = UserHandle.getUserHandleForUid(Binder.getCallingUid()); mAppOps.checkPackage(Binder.getCallingUid(), callingPackage); Loading Loading @@ -3412,7 +3419,7 @@ public class GattService extends ProfileService { } } void continuePiStartScan(int scannerId, ScannerMap.App app) { void continuePiStartScan(int scannerId, TransitionalScanHelper.ScannerMap.App app) { final PendingIntentInfo piInfo = app.info; final ScanClient scanClient = new ScanClient(scannerId, piInfo.settings, piInfo.filters, piInfo.callingUid); Loading @@ -3427,7 +3434,8 @@ public class GattService extends ProfileService { scanClient.associatedDevices = app.mAssociatedDevices; scanClient.hasDisavowedLocation = app.mHasDisavowedLocation; AppScanStats scanStats = mScannerMap.getAppScanStatsById(scannerId); AppScanStats scanStats = mTransitionalScanHelper.getScannerMap().getAppScanStatsById(scannerId); if (scanStats != null) { scanClient.stats = scanStats; boolean isFilteredScan = (piInfo.filters != null) && !piInfo.filters.isEmpty(); Loading Loading @@ -3463,7 +3471,7 @@ public class GattService extends ProfileService { } AppScanStats app = null; app = mScannerMap.getAppScanStatsById(scannerId); app = mTransitionalScanHelper.getScannerMap().getAppScanStatsById(scannerId); if (app != null) { app.recordScanStop(scannerId); } Loading @@ -3479,7 +3487,8 @@ public class GattService extends ProfileService { } PendingIntentInfo pii = new PendingIntentInfo(); pii.intent = intent; ScannerMap.App app = mScannerMap.getByContextInfo(pii); TransitionalScanHelper.ScannerMap.App app = mTransitionalScanHelper.getScannerMap().getByContextInfo(pii); if (VDBG) { Log.d(TAG, "stopScan(PendingIntent): app found = " + app); } Loading Loading @@ -5102,8 +5111,9 @@ public class GattService extends ProfileService { void dumpRegisterId(StringBuilder sb) { sb.append(" Scanner:\n"); for (Integer appId : mScannerMap.getAllAppsIds()) { println(sb, " app_if: " + appId + ", appName: " + mScannerMap.getById(appId).name); for (Integer appId : mTransitionalScanHelper.getScannerMap().getAllAppsIds()) { println(sb, " app_if: " + appId + ", appName: " + mTransitionalScanHelper.getScannerMap().getById(appId).name); } sb.append(" Client:\n"); for (Integer appId : mClientMap.getAllAppsIds()) { Loading @@ -5130,7 +5140,7 @@ public class GattService extends ProfileService { dumpRegisterId(sb); sb.append("GATT Scanner Map\n"); mScannerMap.dump(sb); mTransitionalScanHelper.getScannerMap().dump(sb); sb.append("GATT Advertiser Map\n"); mAdvertiserMap.dumpAdvertiser(sb); Loading android/app/src/com/android/bluetooth/le_scan/ScanManager.java +2 −1 Original line number Diff line number Diff line Loading @@ -1922,7 +1922,8 @@ public class ScanManager { new ActivityManager.OnUidImportanceListener() { @Override public void onUidImportance(final int uid, final int importance) { if (mService.mScannerMap.getAppScanStatsByUid(uid) != null) { if (mService.mTransitionalScanHelper.getScannerMap().getAppScanStatsByUid(uid) != null) { Message message = new Message(); message.what = MSG_IMPORTANCE_CHANGE; message.obj = new UidImportance(uid, importance); Loading android/app/src/com/android/bluetooth/le_scan/TransitionalScanHelper.java 0 → 100644 +49 −0 Original line number Diff line number Diff line /* * 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. * 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.bluetooth.le.IScannerCallback; import com.android.bluetooth.gatt.ContextMap; import com.android.bluetooth.gatt.GattService; import com.android.internal.annotations.VisibleForTesting; /** * A helper class which contains all scan related functions extracted from {@link * com.android.bluetooth.gatt.GattService}. The purpose of this class is to preserve scan * functionality within GattService and provide the same functionality in a new scan dedicated * {@link com.android.bluetooth.btservice.ProfileService} when introduced. * * @hide */ public class TransitionalScanHelper { /** List of our registered scanners. */ public static class ScannerMap extends ContextMap<IScannerCallback, GattService.PendingIntentInfo> {} private ScannerMap mScannerMap = new ScannerMap(); public ScannerMap getScannerMap() { return mScannerMap; } @VisibleForTesting public void setScannerMap(ScannerMap scannerMap) { mScannerMap = scannerMap; } } android/app/tests/unit/src/com/android/bluetooth/gatt/GattServiceTest.java +6 −4 Original line number Diff line number Diff line Loading @@ -61,8 +61,10 @@ import com.android.bluetooth.le_scan.AppScanStats; import com.android.bluetooth.le_scan.PeriodicScanManager; import com.android.bluetooth.le_scan.ScanClient; import com.android.bluetooth.le_scan.ScanManager; import com.android.bluetooth.le_scan.TransitionalScanHelper; import com.android.bluetooth.flags.Flags; import org.junit.After; import org.junit.Assert; import org.junit.Assume; Loading Loading @@ -97,8 +99,8 @@ public class GattServiceTest { private Context mTargetContext; private GattService mService; @Mock private GattService.ClientMap mClientMap; @Mock private GattService.ScannerMap mScannerMap; @Mock private GattService.ScannerMap.App mApp; @Mock private TransitionalScanHelper.ScannerMap mScannerMap; @Mock private TransitionalScanHelper.ScannerMap.App mApp; @Mock private GattService.PendingIntentInfo mPiInfo; @Mock private PeriodicScanManager mPeriodicScanManager; @Mock private ScanManager mScanManager; Loading Loading @@ -158,7 +160,7 @@ public class GattServiceTest { mService.start(); mService.mClientMap = mClientMap; mService.mScannerMap = mScannerMap; mService.mTransitionalScanHelper.setScannerMap(mScannerMap); mService.mReliableQueue = mReliableQueue; mService.mServerMap = mServerMap; } Loading Loading @@ -246,7 +248,7 @@ public class GattServiceTest { mService.connectionParameterUpdate(clientIf, address, connectionPriority, mAttributionSource); connectionPriority = BluetoothGatt.CONNECTION_PRIORITY_BALANCED;; connectionPriority = BluetoothGatt.CONNECTION_PRIORITY_BALANCED; mService.connectionParameterUpdate(clientIf, address, connectionPriority, mAttributionSource); Loading Loading
android/app/src/com/android/bluetooth/gatt/ContextMap.java +9 −9 Original line number Diff line number Diff line Loading @@ -211,7 +211,7 @@ public class ContextMap<C, T> { private final Object mConnectionsLock = new Object(); /** Add an entry to the application context list. */ App add( protected App add( UUID uuid, WorkSource workSource, C callback, Loading Loading @@ -292,7 +292,7 @@ public class ContextMap<C, T> { /** * Remove the context for a given application ID. */ void remove(int id) { protected void remove(int id) { boolean find = false; synchronized (mAppsLock) { Iterator<App> i = mApps.iterator(); Loading @@ -312,7 +312,7 @@ public class ContextMap<C, T> { } } List<Integer> getAllAppsIds() { protected List<Integer> getAllAppsIds() { List<Integer> appIds = new ArrayList(); synchronized (mAppsLock) { Iterator<App> i = mApps.iterator(); Loading Loading @@ -370,7 +370,7 @@ public class ContextMap<C, T> { /** * Get an application context by ID. */ App getById(int id) { protected App getById(int id) { synchronized (mAppsLock) { Iterator<App> i = mApps.iterator(); while (i.hasNext()) { Loading @@ -387,7 +387,7 @@ public class ContextMap<C, T> { /** * Get an application context by UUID. */ App getByUuid(UUID uuid) { protected App getByUuid(UUID uuid) { synchronized (mAppsLock) { Iterator<App> i = mApps.iterator(); while (i.hasNext()) { Loading Loading @@ -421,7 +421,7 @@ public class ContextMap<C, T> { /** * Get an application context by the context info object. */ App getByContextInfo(T contextInfo) { protected App getByContextInfo(T contextInfo) { synchronized (mAppsLock) { Iterator<App> i = mApps.iterator(); while (i.hasNext()) { Loading @@ -438,7 +438,7 @@ public class ContextMap<C, T> { /** * Get Logging info by ID */ AppScanStats getAppScanStatsById(int id) { protected AppScanStats getAppScanStatsById(int id) { App temp = getById(id); if (temp != null) { return temp.appScanStats; Loading Loading @@ -674,7 +674,7 @@ public class ContextMap<C, T> { /** * Erases all application context entries. */ void clear() { protected void clear() { synchronized (mAppsLock) { Iterator<App> i = mApps.iterator(); while (i.hasNext()) { Loading Loading @@ -713,7 +713,7 @@ public class ContextMap<C, T> { /** * Logs debug information. */ void dump(StringBuilder sb) { protected void dump(StringBuilder sb) { sb.append(" Entries: " + mAppScanStats.size() + "\n\n"); Iterator<Map.Entry<Integer, AppScanStats>> it = mAppScanStats.entrySet().iterator(); Loading
android/app/src/com/android/bluetooth/gatt/GattService.java +43 −33 Original line number Diff line number Diff line Loading @@ -100,6 +100,7 @@ import com.android.bluetooth.le_scan.AppScanStats; import com.android.bluetooth.le_scan.PeriodicScanManager; import com.android.bluetooth.le_scan.ScanClient; import com.android.bluetooth.le_scan.ScanManager; import com.android.bluetooth.le_scan.TransitionalScanHelper; import com.android.bluetooth.util.NumberUtils; import com.android.internal.annotations.VisibleForTesting; import com.android.modules.utils.SynchronousResultReceiver; Loading Loading @@ -213,7 +214,7 @@ public class GattService extends ProfileService { /** * Keep the arguments passed in for the PendingIntent. */ class PendingIntentInfo { public static class PendingIntentInfo { public PendingIntent intent; public ScanSettings settings; public List<ScanFilter> filters; Loading @@ -237,12 +238,7 @@ public class GattService extends ProfileService { } }; /** * List of our registered scanners. */ public static class ScannerMap extends ContextMap<IScannerCallback, PendingIntentInfo> {} public ScannerMap mScannerMap = new ScannerMap(); public final TransitionalScanHelper mTransitionalScanHelper = new TransitionalScanHelper(); /** * List of our registered advertisers. Loading Loading @@ -394,7 +390,7 @@ public class GattService extends ProfileService { if (DBG) { Log.d(TAG, "stop()"); } mScannerMap.clear(); mTransitionalScanHelper.getScannerMap().clear(); mAdvertiserMap.clear(); mClientMap.clear(); if (Flags.gattCleanupRestrictedHandles()) { Loading Loading @@ -2020,7 +2016,8 @@ public class GattService extends ProfileService { byte[] legacyAdvData = Arrays.copyOfRange(advData, 0, 62); for (ScanClient client : mScanManager.getRegularScanQueue()) { ScannerMap.App app = mScannerMap.getById(client.scannerId); TransitionalScanHelper.ScannerMap.App app = mTransitionalScanHelper.getScannerMap().getById(client.scannerId); if (app == null) { if (VDBG) { Log.d(TAG, "App is null; skip."); Loading Loading @@ -2112,7 +2109,7 @@ public class GattService extends ProfileService { if (Flags.leScanFixRemoteException()) { handleDeadScanClient(client); } else { mScannerMap.remove(client.scannerId); mTransitionalScanHelper.getScannerMap().remove(client.scannerId); mScanManager.stopScan(client.scannerId); } } Loading Loading @@ -2161,7 +2158,8 @@ public class GattService extends ProfileService { } // First check the callback map ScannerMap.App cbApp = mScannerMap.getByUuid(uuid); TransitionalScanHelper.ScannerMap.App cbApp = mTransitionalScanHelper.getScannerMap().getByUuid(uuid); if (cbApp != null) { if (status == 0) { cbApp.id = scannerId; Loading @@ -2173,7 +2171,7 @@ public class GattService extends ProfileService { continuePiStartScan(scannerId, cbApp); } } else { mScannerMap.remove(scannerId); mTransitionalScanHelper.getScannerMap().remove(scannerId); } if (cbApp.callback != null) { cbApp.callback.onScannerRegistered(status, scannerId); Loading Loading @@ -2802,7 +2800,8 @@ public class GattService extends ProfileService { Set<ScanResult> results = parseBatchScanResults(numRecords, reportType, recordData); if (reportType == ScanManager.SCAN_RESULT_TYPE_TRUNCATED) { // We only support single client for truncated mode. ScannerMap.App app = mScannerMap.getById(scannerId); TransitionalScanHelper.ScannerMap.App app = mTransitionalScanHelper.getScannerMap().getById(scannerId); if (app == null) { return; } Loading Loading @@ -2853,7 +2852,7 @@ public class GattService extends ProfileService { mScanManager.callbackDone(scannerId, status); } private void sendBatchScanResults(ScannerMap.App app, ScanClient client, private void sendBatchScanResults(TransitionalScanHelper.ScannerMap.App app, ScanClient client, ArrayList<ScanResult> results) { try { if (app.callback != null) { Loading @@ -2880,7 +2879,7 @@ public class GattService extends ProfileService { if (Flags.leScanFixRemoteException()) { handleDeadScanClient(client); } else { mScannerMap.remove(client.scannerId); mTransitionalScanHelper.getScannerMap().remove(client.scannerId); mScanManager.stopScan(client.scannerId); } } Loading @@ -2889,7 +2888,8 @@ public class GattService extends ProfileService { // Check and deliver scan results for different scan clients. private void deliverBatchScan(ScanClient client, Set<ScanResult> allResults) throws RemoteException { ScannerMap.App app = mScannerMap.getById(client.scannerId); TransitionalScanHelper.ScannerMap.App app = mTransitionalScanHelper.getScannerMap().getById(client.scannerId); if (app == null) { return; } Loading Loading @@ -3050,7 +3050,8 @@ public class GattService extends ProfileService { + trackingInfo.getAdvState()); } ScannerMap.App app = mScannerMap.getById(trackingInfo.getClientIf()); TransitionalScanHelper.ScannerMap.App app = mTransitionalScanHelper.getScannerMap().getById(trackingInfo.getClientIf()); if (app == null || (app.callback == null && app.info == null)) { Log.e(TAG, "app or callback is null"); return; Loading Loading @@ -3096,7 +3097,8 @@ public class GattService extends ProfileService { } void onScanParamSetupCompleted(int status, int scannerId) throws RemoteException { ScannerMap.App app = mScannerMap.getById(scannerId); TransitionalScanHelper.ScannerMap.App app = mTransitionalScanHelper.getScannerMap().getById(scannerId); if (app == null || app.callback == null) { Log.e(TAG, "Advertise app or callback is null"); return; Loading @@ -3108,7 +3110,8 @@ public class GattService extends ProfileService { // callback from ScanManager for dispatch of errors apps. public void onScanManagerErrorCallback(int scannerId, int errorCode) throws RemoteException { ScannerMap.App app = mScannerMap.getById(scannerId); TransitionalScanHelper.ScannerMap.App app = mTransitionalScanHelper.getScannerMap().getById(scannerId); if (app == null || (app.callback == null && app.info == null)) { Log.e(TAG, "App or callback is null"); return; Loading Loading @@ -3225,7 +3228,8 @@ public class GattService extends ProfileService { enforceImpersonatationPermissionIfNeeded(workSource); AppScanStats app = mScannerMap.getAppScanStatsByUid(Binder.getCallingUid()); AppScanStats app = mTransitionalScanHelper.getScannerMap() .getAppScanStatsByUid(Binder.getCallingUid()); if (app != null && app.isScanningTooFrequently() && !Utils.checkCallerHasPrivilegedPermission(this)) { Log.e(TAG, "App '" + app.appName + "' is scanning too frequently"); Loading @@ -3233,7 +3237,8 @@ public class GattService extends ProfileService { return; } mScannerMap.add(uuid, workSource, callback, null, this); mTransitionalScanHelper .getScannerMap().add(uuid, workSource, callback, null, this); mScanManager.registerScanner(uuid); } Loading @@ -3247,7 +3252,7 @@ public class GattService extends ProfileService { if (DBG) { Log.d(TAG, "unregisterScanner() - scannerId=" + scannerId); } mScannerMap.remove(scannerId); mTransitionalScanHelper.getScannerMap().remove(scannerId); mScanManager.unregisterScanner(scannerId); } Loading Loading @@ -3319,8 +3324,9 @@ public class GattService extends ProfileService { Utils.checkCallerHasScanWithoutLocationPermission(this); scanClient.associatedDevices = getAssociatedDevices(callingPackage); AppScanStats app = mScannerMap.getAppScanStatsById(scannerId); ScannerMap.App cbApp = mScannerMap.getById(scannerId); AppScanStats app = mTransitionalScanHelper.getScannerMap().getAppScanStatsById(scannerId); TransitionalScanHelper.ScannerMap.App cbApp = mTransitionalScanHelper.getScannerMap().getById(scannerId); if (app != null) { scanClient.stats = app; boolean isFilteredScan = (filters != null) && !filters.isEmpty(); Loading Loading @@ -3367,12 +3373,13 @@ public class GattService extends ProfileService { } // Don't start scan if the Pi scan already in mScannerMap. if (mScannerMap.getByContextInfo(piInfo) != null) { if (mTransitionalScanHelper.getScannerMap().getByContextInfo(piInfo) != null) { Log.d(TAG, "Don't startScan(PI) since the same Pi scan already in mScannerMap."); return; } ScannerMap.App app = mScannerMap.add(uuid, null, null, piInfo, this); TransitionalScanHelper.ScannerMap.App app = mTransitionalScanHelper.getScannerMap().add(uuid, null, null, piInfo, this); app.mUserHandle = UserHandle.getUserHandleForUid(Binder.getCallingUid()); mAppOps.checkPackage(Binder.getCallingUid(), callingPackage); Loading Loading @@ -3412,7 +3419,7 @@ public class GattService extends ProfileService { } } void continuePiStartScan(int scannerId, ScannerMap.App app) { void continuePiStartScan(int scannerId, TransitionalScanHelper.ScannerMap.App app) { final PendingIntentInfo piInfo = app.info; final ScanClient scanClient = new ScanClient(scannerId, piInfo.settings, piInfo.filters, piInfo.callingUid); Loading @@ -3427,7 +3434,8 @@ public class GattService extends ProfileService { scanClient.associatedDevices = app.mAssociatedDevices; scanClient.hasDisavowedLocation = app.mHasDisavowedLocation; AppScanStats scanStats = mScannerMap.getAppScanStatsById(scannerId); AppScanStats scanStats = mTransitionalScanHelper.getScannerMap().getAppScanStatsById(scannerId); if (scanStats != null) { scanClient.stats = scanStats; boolean isFilteredScan = (piInfo.filters != null) && !piInfo.filters.isEmpty(); Loading Loading @@ -3463,7 +3471,7 @@ public class GattService extends ProfileService { } AppScanStats app = null; app = mScannerMap.getAppScanStatsById(scannerId); app = mTransitionalScanHelper.getScannerMap().getAppScanStatsById(scannerId); if (app != null) { app.recordScanStop(scannerId); } Loading @@ -3479,7 +3487,8 @@ public class GattService extends ProfileService { } PendingIntentInfo pii = new PendingIntentInfo(); pii.intent = intent; ScannerMap.App app = mScannerMap.getByContextInfo(pii); TransitionalScanHelper.ScannerMap.App app = mTransitionalScanHelper.getScannerMap().getByContextInfo(pii); if (VDBG) { Log.d(TAG, "stopScan(PendingIntent): app found = " + app); } Loading Loading @@ -5102,8 +5111,9 @@ public class GattService extends ProfileService { void dumpRegisterId(StringBuilder sb) { sb.append(" Scanner:\n"); for (Integer appId : mScannerMap.getAllAppsIds()) { println(sb, " app_if: " + appId + ", appName: " + mScannerMap.getById(appId).name); for (Integer appId : mTransitionalScanHelper.getScannerMap().getAllAppsIds()) { println(sb, " app_if: " + appId + ", appName: " + mTransitionalScanHelper.getScannerMap().getById(appId).name); } sb.append(" Client:\n"); for (Integer appId : mClientMap.getAllAppsIds()) { Loading @@ -5130,7 +5140,7 @@ public class GattService extends ProfileService { dumpRegisterId(sb); sb.append("GATT Scanner Map\n"); mScannerMap.dump(sb); mTransitionalScanHelper.getScannerMap().dump(sb); sb.append("GATT Advertiser Map\n"); mAdvertiserMap.dumpAdvertiser(sb); Loading
android/app/src/com/android/bluetooth/le_scan/ScanManager.java +2 −1 Original line number Diff line number Diff line Loading @@ -1922,7 +1922,8 @@ public class ScanManager { new ActivityManager.OnUidImportanceListener() { @Override public void onUidImportance(final int uid, final int importance) { if (mService.mScannerMap.getAppScanStatsByUid(uid) != null) { if (mService.mTransitionalScanHelper.getScannerMap().getAppScanStatsByUid(uid) != null) { Message message = new Message(); message.what = MSG_IMPORTANCE_CHANGE; message.obj = new UidImportance(uid, importance); Loading
android/app/src/com/android/bluetooth/le_scan/TransitionalScanHelper.java 0 → 100644 +49 −0 Original line number Diff line number Diff line /* * 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. * 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.bluetooth.le.IScannerCallback; import com.android.bluetooth.gatt.ContextMap; import com.android.bluetooth.gatt.GattService; import com.android.internal.annotations.VisibleForTesting; /** * A helper class which contains all scan related functions extracted from {@link * com.android.bluetooth.gatt.GattService}. The purpose of this class is to preserve scan * functionality within GattService and provide the same functionality in a new scan dedicated * {@link com.android.bluetooth.btservice.ProfileService} when introduced. * * @hide */ public class TransitionalScanHelper { /** List of our registered scanners. */ public static class ScannerMap extends ContextMap<IScannerCallback, GattService.PendingIntentInfo> {} private ScannerMap mScannerMap = new ScannerMap(); public ScannerMap getScannerMap() { return mScannerMap; } @VisibleForTesting public void setScannerMap(ScannerMap scannerMap) { mScannerMap = scannerMap; } }
android/app/tests/unit/src/com/android/bluetooth/gatt/GattServiceTest.java +6 −4 Original line number Diff line number Diff line Loading @@ -61,8 +61,10 @@ import com.android.bluetooth.le_scan.AppScanStats; import com.android.bluetooth.le_scan.PeriodicScanManager; import com.android.bluetooth.le_scan.ScanClient; import com.android.bluetooth.le_scan.ScanManager; import com.android.bluetooth.le_scan.TransitionalScanHelper; import com.android.bluetooth.flags.Flags; import org.junit.After; import org.junit.Assert; import org.junit.Assume; Loading Loading @@ -97,8 +99,8 @@ public class GattServiceTest { private Context mTargetContext; private GattService mService; @Mock private GattService.ClientMap mClientMap; @Mock private GattService.ScannerMap mScannerMap; @Mock private GattService.ScannerMap.App mApp; @Mock private TransitionalScanHelper.ScannerMap mScannerMap; @Mock private TransitionalScanHelper.ScannerMap.App mApp; @Mock private GattService.PendingIntentInfo mPiInfo; @Mock private PeriodicScanManager mPeriodicScanManager; @Mock private ScanManager mScanManager; Loading Loading @@ -158,7 +160,7 @@ public class GattServiceTest { mService.start(); mService.mClientMap = mClientMap; mService.mScannerMap = mScannerMap; mService.mTransitionalScanHelper.setScannerMap(mScannerMap); mService.mReliableQueue = mReliableQueue; mService.mServerMap = mServerMap; } Loading Loading @@ -246,7 +248,7 @@ public class GattServiceTest { mService.connectionParameterUpdate(clientIf, address, connectionPriority, mAttributionSource); connectionPriority = BluetoothGatt.CONNECTION_PRIORITY_BALANCED;; connectionPriority = BluetoothGatt.CONNECTION_PRIORITY_BALANCED; mService.connectionParameterUpdate(clientIf, address, connectionPriority, mAttributionSource); Loading