Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit aa21a808 authored by Omair Kamil's avatar Omair Kamil
Browse files

Move scanning code out of GattService.

Test: atest BluetoothInstrumentationTests, atest BumbleBluetoothTests
Flag: EXEMPT - mechanical refactor
Bug: 327503826
Bug: 267361243

Change-Id: I5461986304446ce440bfd6ec819e567f735dace3
parent c3aa1ff8
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -2827,10 +2827,10 @@ static int register_com_android_bluetooth_gatt_(JNIEnv* env) {
       &method_onBatchScanThresholdCrossed},
      {"createOnTrackAdvFoundLostObject",
       "(II[BI[BIIILjava/lang/String;IIII)"
       "Lcom/android/bluetooth/gatt/AdvtFilterOnFoundOnLostInfo;",
       "Lcom/android/bluetooth/le_scan/AdvtFilterOnFoundOnLostInfo;",
       &method_createOnTrackAdvFoundLostObject},
      {"onTrackAdvFoundLost",
       "(Lcom/android/bluetooth/gatt/AdvtFilterOnFoundOnLostInfo;)V",
       "(Lcom/android/bluetooth/le_scan/AdvtFilterOnFoundOnLostInfo;)V",
       &method_onTrackAdvFoundLost},
      {"onScanParamSetupCompleted", "(II)V", &method_onScanParamSetupCompleted},
      {"getSampleGattDbElement", "()Lcom/android/bluetooth/gatt/GattDbElement;",
+4 −3
Original line number Diff line number Diff line
@@ -16,11 +16,12 @@
package com.android.bluetooth.gatt;

/**
 * Helper class that keeps track of callback parameters for app callbacks.
 * These are held during congestion and reported when congestion clears.
 * Helper class that keeps track of callback parameters for app callbacks. These are held during
 * congestion and reported when congestion clears.
 *
 * @hide
 */
/* package */ class CallbackInfo {
public class CallbackInfo {
    public String address;
    public int status;
    public int handle;
+42 −57
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.bluetooth.gatt;
import android.bluetooth.le.AdvertiseData;
import android.bluetooth.le.AdvertisingSetParameters;
import android.bluetooth.le.PeriodicAdvertisingParameters;
import android.content.Context;
import android.os.Binder;
import android.os.IBinder;
import android.os.IInterface;
@@ -27,10 +28,11 @@ import android.os.UserHandle;
import android.os.WorkSource;
import android.util.Log;

import androidx.annotation.VisibleForTesting;

import com.android.bluetooth.BluetoothMethodProxy;
import com.android.bluetooth.le_scan.AppScanStats;
import com.android.bluetooth.le_scan.TransitionalScanHelper;
import com.android.bluetooth.le_scan.TransitionalScanHelper.PendingIntentInfo;
import com.android.internal.annotations.GuardedBy;

import com.google.common.collect.EvictingQueue;
@@ -98,27 +100,27 @@ public class ContextMap<C, T> {
        public Boolean isCongested = false;

        /** Whether the calling app has location permission */
        boolean hasLocationPermission;
        public boolean hasLocationPermission;

        /** Whether the calling app has bluetooth privileged permission */
        boolean hasBluetoothPrivilegedPermission;
        public boolean hasBluetoothPrivilegedPermission;

        /** The user handle of the app that started the scan */
        UserHandle mUserHandle;
        public UserHandle mUserHandle;

        /** Whether the calling app has the network settings permission */
        boolean mHasNetworkSettingsPermission;
        public boolean mHasNetworkSettingsPermission;

        /** Whether the calling app has the network setup wizard permission */
        boolean mHasNetworkSetupWizardPermission;
        public boolean mHasNetworkSetupWizardPermission;

        /** Whether the calling app has the network setup wizard permission */
        boolean mHasScanWithoutLocationPermission;
        public boolean mHasScanWithoutLocationPermission;

        /** Whether the calling app has disavowed the use of bluetooth for location */
        boolean mHasDisavowedLocation;
        public boolean mHasDisavowedLocation;

        boolean mEligibleForSanitizedExposureNotification;
        public boolean mEligibleForSanitizedExposureNotification;

        public List<String> mAssociatedDevices;

@@ -145,10 +147,8 @@ public class ContextMap<C, T> {
            this.name = name;
        }

        /**
         * Link death recipient
         */
        void linkToDeath(IBinder.DeathRecipient deathRecipient) {
        /** Link death recipient */
        public void linkToDeath(IBinder.DeathRecipient deathRecipient) {
            // It might not be a binder object
            if (callback == null) {
                return;
@@ -162,10 +162,8 @@ public class ContextMap<C, T> {
            }
        }

        /**
         * Unlink death recipient
         */
        void unlinkToDeath() {
        /** Unlink death recipient */
        public void unlinkToDeath() {
            if (mDeathRecipient != null) {
                try {
                    IBinder binder = ((IInterface) callback).asBinder();
@@ -176,11 +174,11 @@ public class ContextMap<C, T> {
            }
        }

        void queueCallback(CallbackInfo callbackInfo) {
        public void queueCallback(CallbackInfo callbackInfo) {
            mCongestionQueue.add(callbackInfo);
        }

        CallbackInfo popQueuedCallback() {
        public CallbackInfo popQueuedCallback() {
            if (mCongestionQueue.size() == 0) {
                return null;
            }
@@ -210,12 +208,13 @@ public class ContextMap<C, T> {
    private final Object mConnectionsLock = new Object();

    /** Add an entry to the application context list. */
    protected App add(
    public App add(
            UUID uuid,
            WorkSource workSource,
            C callback,
            GattService.PendingIntentInfo piInfo,
            GattService service) {
            PendingIntentInfo piInfo,
            Context context,
            TransitionalScanHelper scanHelper) {
        int appUid;
        String appName = null;
        if (piInfo != null) {
@@ -223,16 +222,18 @@ public class ContextMap<C, T> {
            appName = piInfo.callingPackage;
        } else {
            appUid = Binder.getCallingUid();
            appName = service.getPackageManager().getNameForUid(appUid);
            appName = context.getPackageManager().getNameForUid(appUid);
        }
        if (appName == null) {
            // Assign an app name if one isn't found
            appName = "Unknown App (UID: " + appUid + ")";
        }
        synchronized (mAppsLock) {
            // TODO(b/327849650): AppScanStats appears to be only needed for the ScannerMap.
            //                    Consider refactoring this.
            AppScanStats appScanStats = mAppScanStats.get(appUid);
            if (appScanStats == null) {
                appScanStats = new AppScanStats(appName, workSource, this, service);
                appScanStats = new AppScanStats(appName, workSource, this, context, scanHelper);
                mAppScanStats.put(appUid, appScanStats);
            }
            App app = new App(uuid, callback, (T) piInfo, appName, appScanStats);
@@ -242,10 +243,8 @@ public class ContextMap<C, T> {
        }
    }

    /**
     * Add an entry to the application context list for advertiser.
     */
    App add(int id, C callback, GattService service) {
    /** Add an entry to the application context list for advertiser. */
    public App add(int id, C callback, GattService service) {
        int appUid = Binder.getCallingUid();
        String appName = service.getPackageManager().getNameForUid(appUid);
        if (appName == null) {
@@ -270,10 +269,8 @@ public class ContextMap<C, T> {
        }
    }

    /**
     * Remove the context for a given UUID
     */
    void remove(UUID uuid) {
    /** Remove the context for a given UUID */
    public void remove(UUID uuid) {
        synchronized (mAppsLock) {
            Iterator<App> i = mApps.iterator();
            while (i.hasNext()) {
@@ -288,10 +285,8 @@ public class ContextMap<C, T> {
        }
    }

    /**
     * Remove the context for a given application ID.
     */
    protected void remove(int id) {
    /** Remove the context for a given application ID. */
    public void remove(int id) {
        boolean find = false;
        synchronized (mAppsLock) {
            Iterator<App> i = mApps.iterator();
@@ -311,7 +306,7 @@ public class ContextMap<C, T> {
        }
    }

    protected List<Integer> getAllAppsIds() {
    public List<Integer> getAllAppsIds() {
        List<Integer> appIds = new ArrayList();
        synchronized (mAppsLock) {
            Iterator<App> i = mApps.iterator();
@@ -366,10 +361,8 @@ public class ContextMap<C, T> {
        }
    }

    /**
     * Get an application context by ID.
     */
    protected App getById(int id) {
    /** Get an application context by ID. */
    public App getById(int id) {
        synchronized (mAppsLock) {
            Iterator<App> i = mApps.iterator();
            while (i.hasNext()) {
@@ -383,10 +376,8 @@ public class ContextMap<C, T> {
        return null;
    }

    /**
     * Get an application context by UUID.
     */
    protected App getByUuid(UUID uuid) {
    /** Get an application context by UUID. */
    public App getByUuid(UUID uuid) {
        synchronized (mAppsLock) {
            Iterator<App> i = mApps.iterator();
            while (i.hasNext()) {
@@ -417,10 +408,8 @@ public class ContextMap<C, T> {
        return null;
    }

    /**
     * Get an application context by the context info object.
     */
    protected App getByContextInfo(T contextInfo) {
    /** Get an application context by the context info object. */
    public App getByContextInfo(T contextInfo) {
        synchronized (mAppsLock) {
            Iterator<App> i = mApps.iterator();
            while (i.hasNext()) {
@@ -434,10 +423,8 @@ public class ContextMap<C, T> {
        return null;
    }

    /**
     * Get Logging info by ID
     */
    protected AppScanStats getAppScanStatsById(int id) {
    /** Get Logging info by ID */
    public AppScanStats getAppScanStatsById(int id) {
        App temp = getById(id);
        if (temp != null) {
            return temp.appScanStats;
@@ -670,10 +657,8 @@ public class ContextMap<C, T> {
        return currentConnections;
    }

    /**
     * Erases all application context entries.
     */
    protected void clear() {
    /** Erases all application context entries. */
    public void clear() {
        synchronized (mAppsLock) {
            Iterator<App> i = mApps.iterator();
            while (i.hasNext()) {
+49 −15
Original line number Diff line number Diff line
@@ -18,6 +18,8 @@ package com.android.bluetooth.gatt;

import android.os.RemoteException;

import com.android.bluetooth.le_scan.AdvtFilterOnFoundOnLostInfo;
import com.android.bluetooth.le_scan.TransitionalScanHelper;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;

@@ -70,13 +72,24 @@ public class GattNativeInterface {
    void onScanResult(int eventType, int addressType, String address, int primaryPhy,
            int secondaryPhy, int advertisingSid, int txPower, int rssi, int periodicAdvInt,
            byte[] advData, String originalAddress) {
        getGattService().onScanResult(eventType, addressType, address, primaryPhy, secondaryPhy,
                advertisingSid, txPower, rssi, periodicAdvInt, advData, originalAddress);
        getTransitionalScanHelper()
                .onScanResult(
                        eventType,
                        addressType,
                        address,
                        primaryPhy,
                        secondaryPhy,
                        advertisingSid,
                        txPower,
                        rssi,
                        periodicAdvInt,
                        advData,
                        originalAddress);
    }

    void onScannerRegistered(int status, int scannerId, long uuidLsb, long uuidMsb)
            throws RemoteException {
        getGattService().onScannerRegistered(status, scannerId, uuidLsb, uuidMsb);
        getTransitionalScanHelper().onScannerRegistered(status, scannerId, uuidLsb, uuidMsb);
    }

    void onClientRegistered(int status, int clientIf, long uuidLsb, long uuidMsb)
@@ -187,50 +200,65 @@ public class GattNativeInterface {
    }

    void onScanFilterEnableDisabled(int action, int status, int clientIf) {
        getGattService().onScanFilterEnableDisabled(action, status, clientIf);
        getTransitionalScanHelper().onScanFilterEnableDisabled(action, status, clientIf);
    }

    void onScanFilterParamsConfigured(int action, int status, int clientIf, int availableSpace) {
        getGattService().onScanFilterParamsConfigured(action, status, clientIf, availableSpace);
        getTransitionalScanHelper()
                .onScanFilterParamsConfigured(action, status, clientIf, availableSpace);
    }

    void onScanFilterConfig(int action, int status, int clientIf, int filterType,
            int availableSpace) {
        getGattService().onScanFilterConfig(action, status, clientIf, filterType, availableSpace);
        getTransitionalScanHelper()
                .onScanFilterConfig(action, status, clientIf, filterType, availableSpace);
    }

    void onBatchScanStorageConfigured(int status, int clientIf) {
        getGattService().onBatchScanStorageConfigured(status, clientIf);
        getTransitionalScanHelper().onBatchScanStorageConfigured(status, clientIf);
    }

    void onBatchScanStartStopped(int startStopAction, int status, int clientIf) {
        getGattService().onBatchScanStartStopped(startStopAction, status, clientIf);
        getTransitionalScanHelper().onBatchScanStartStopped(startStopAction, status, clientIf);
    }

    void onBatchScanReports(int status, int scannerId, int reportType, int numRecords,
            byte[] recordData) throws RemoteException {
        getGattService().onBatchScanReports(status, scannerId, reportType, numRecords, recordData);
        getTransitionalScanHelper()
                .onBatchScanReports(status, scannerId, reportType, numRecords, recordData);
    }

    void onBatchScanThresholdCrossed(int clientIf) {
        getGattService().onBatchScanThresholdCrossed(clientIf);
        getTransitionalScanHelper().onBatchScanThresholdCrossed(clientIf);
    }

    AdvtFilterOnFoundOnLostInfo createOnTrackAdvFoundLostObject(int clientIf, int advPktLen,
            byte[] advPkt, int scanRspLen, byte[] scanRsp, int filtIndex, int advState,
            int advInfoPresent, String address, int addrType, int txPower, int rssiValue,
            int timeStamp) {
        return getGattService().createOnTrackAdvFoundLostObject(clientIf, advPktLen, advPkt,
                scanRspLen, scanRsp, filtIndex, advState, advInfoPresent, address, addrType,
                txPower, rssiValue, timeStamp);
        return getTransitionalScanHelper()
                .createOnTrackAdvFoundLostObject(
                        clientIf,
                        advPktLen,
                        advPkt,
                        scanRspLen,
                        scanRsp,
                        filtIndex,
                        advState,
                        advInfoPresent,
                        address,
                        addrType,
                        txPower,
                        rssiValue,
                        timeStamp);
    }

    void onTrackAdvFoundLost(AdvtFilterOnFoundOnLostInfo trackingInfo) throws RemoteException {
        getGattService().onTrackAdvFoundLost(trackingInfo);
        getTransitionalScanHelper().onTrackAdvFoundLost(trackingInfo);
    }

    void onScanParamSetupCompleted(int status, int scannerId) throws RemoteException {
        getGattService().onScanParamSetupCompleted(status, scannerId);
        getTransitionalScanHelper().onScanParamSetupCompleted(status, scannerId);
    }

    void onConfigureMTU(int connId, int status, int mtu) throws RemoteException {
@@ -665,5 +693,11 @@ public class GattNativeInterface {
            int p1, int p2, int p3, int p4, int p5) {
        gattTestNative(command, uuid1Lsb, uuid1Msb, bda1, p1, p2, p3, p4, p5);
    }

    // TODO(b/327849650): Callbacks that reference this helper should be moved into the appropriate
    //                    native interface (ScanNativeInterface, PeriodicScanNativeInterface, etc.).
    private TransitionalScanHelper getTransitionalScanHelper() {
        return mGattService.getTransitionalScanHelper();
    }
}
+7 −3
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.bluetooth.gatt;

import android.content.Context;
import android.os.Looper;
import android.util.Log;

@@ -25,6 +26,7 @@ import com.android.bluetooth.btservice.BluetoothAdapterProxy;
import com.android.bluetooth.le_scan.PeriodicScanManager;
import com.android.bluetooth.le_scan.ScanManager;
import com.android.bluetooth.le_scan.ScanNativeInterface;
import com.android.bluetooth.le_scan.TransitionalScanHelper;

/**
 * Factory class for object initialization to help with unit testing
@@ -75,18 +77,20 @@ public class GattObjectsFactory {
    /**
     * Create an instance of ScanManager
     *
     * @param service a GattService instance
     * @param context a Context instance
     * @param scanHelper a TransitionalScanHelper instance
     * @param adapterService an AdapterService instance
     * @param bluetoothAdapterProxy a bluetoothAdapterProxy instance
     * @param looper the looper to be used for processing messages
     * @return the created ScanManager instance
     */
    public ScanManager createScanManager(
            GattService service,
            Context context,
            TransitionalScanHelper scanHelper,
            AdapterService adapterService,
            BluetoothAdapterProxy bluetoothAdapterProxy,
            Looper looper) {
        return new ScanManager(service, adapterService, bluetoothAdapterProxy, looper);
        return new ScanManager(context, scanHelper, adapterService, bluetoothAdapterProxy, looper);
    }

    public PeriodicScanManager createPeriodicScanManager(AdapterService adapterService) {
Loading