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

Commit ee443474 authored by William Escande's avatar William Escande Committed by Automerger Merge Worker
Browse files

Merge changes from topic "scan_manager_test_flaky_test" into main am: a217daea

parents 12bf80a4 a217daea
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -1285,4 +1285,17 @@ public final class Utils {
    public static @NonNull String formatSimple(@NonNull String format, Object... args) {
        return android.bluetooth.BluetoothUtils.formatSimple(format, args);
    }

    public interface TimeProvider {
        long elapsedRealtime();
    }

    public static final TimeProvider sSystemClock = new SystemClockTimeProvider();

    private static final class SystemClockTimeProvider implements TimeProvider {
        @Override
        public long elapsedRealtime() {
            return android.os.SystemClock.elapsedRealtime();
        }
    }
}
+13 −6
Original line number Diff line number Diff line
@@ -6645,14 +6645,14 @@ public class AdapterService extends Service {
    }

    /** Returns scan upgrade duration in millis. */
    public long getScanUpgradeDurationMillis() {
    public int getScanUpgradeDurationMillis() {
        synchronized (mDeviceConfigLock) {
            return mScanUpgradeDurationMillis;
        }
    }

    /** Returns scan downgrade duration in millis. */
    public long getScanDowngradeDurationMillis() {
    public int getScanDowngradeDurationMillis() {
        synchronized (mDeviceConfigLock) {
            return mScanDowngradeDurationMillis;
        }
@@ -6686,7 +6686,8 @@ public class AdapterService extends Service {
        }
    }

    private class DeviceConfigListener implements DeviceConfig.OnPropertiesChangedListener {
    @VisibleForTesting
    public class DeviceConfigListener implements DeviceConfig.OnPropertiesChangedListener {
        private static final String LOCATION_DENYLIST_NAME = "location_denylist_name";
        private static final String LOCATION_DENYLIST_MAC = "location_denylist_mac";
        private static final String LOCATION_DENYLIST_ADVERTISING_DATA =
@@ -6716,9 +6717,15 @@ public class AdapterService extends Service {

        private static final int DEFAULT_SCAN_QUOTA_COUNT = 5;
        private static final long DEFAULT_SCAN_QUOTA_WINDOW_MILLIS = 30 * SECOND_IN_MILLIS;
        private static final long DEFAULT_SCAN_TIMEOUT_MILLIS = 10 * MINUTE_IN_MILLIS;
        private static final int DEFAULT_SCAN_UPGRADE_DURATION_MILLIS = (int) SECOND_IN_MILLIS * 6;
        private static final int DEFAULT_SCAN_DOWNGRADE_DURATION_BT_CONNECTING_MILLIS =

        @VisibleForTesting
        public static final long DEFAULT_SCAN_TIMEOUT_MILLIS = 10 * MINUTE_IN_MILLIS;

        @VisibleForTesting
        public static final int DEFAULT_SCAN_UPGRADE_DURATION_MILLIS = (int) SECOND_IN_MILLIS * 6;

        @VisibleForTesting
        public static final int DEFAULT_SCAN_DOWNGRADE_DURATION_BT_CONNECTING_MILLIS =
                (int) SECOND_IN_MILLIS * 6;

        public void start() {
+32 −23
Original line number Diff line number Diff line
@@ -16,18 +16,19 @@

package com.android.bluetooth.le_scan;

import static java.util.Objects.requireNonNull;

import android.annotation.Nullable;
import android.bluetooth.BluetoothProtoEnums;
import android.bluetooth.le.ScanFilter;
import android.bluetooth.le.ScanSettings;
import android.content.Context;
import android.os.BatteryStatsManager;
import android.os.Binder;
import android.os.SystemClock;
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;
@@ -71,6 +72,7 @@ public class AppScanStats {
    BatteryStatsManager mBatteryStatsManager;

    private final AdapterService mAdapterService;
    private final TimeProvider mTimeProvider;

    private static Object sLock = new Object();

@@ -170,12 +172,15 @@ public class AppScanStats {
            String name,
            WorkSource source,
            ScannerMap map,
            Context context,
            TransitionalScanHelper scanHelper) {
            AdapterService adapterService,
            TransitionalScanHelper scanHelper,
            TimeProvider timeProvider) {
        mAdapterService = requireNonNull(adapterService);
        mTimeProvider = requireNonNull(timeProvider);
        mAppName = name;
        mScannerMap = map;
        mScanHelper = scanHelper;
        mBatteryStatsManager = context.getSystemService(BatteryStatsManager.class);
        mBatteryStatsManager = adapterService.getSystemService(BatteryStatsManager.class);

        if (source == null) {
            // Bill the caller if the work source isn't passed through
@@ -183,7 +188,6 @@ public class AppScanStats {
        }
        mWorkSource = source;
        mWorkSourceUtil = new WorkSourceUtil(source);
        mAdapterService = Objects.requireNonNull(AdapterService.getAdapterService());
    }

    public synchronized void addResult(int scannerId) {
@@ -250,7 +254,7 @@ public class AppScanStats {
            return;
        }
        this.mScansStarted++;
        startTime = SystemClock.elapsedRealtime();
        startTime = mTimeProvider.elapsedRealtime();

        LastScan scan =
                new LastScan(
@@ -333,7 +337,7 @@ public class AppScanStats {
            return;
        }
        this.mScansStopped++;
        stopTime = SystemClock.elapsedRealtime();
        stopTime = mTimeProvider.elapsedRealtime();
        long scanDuration = stopTime - scan.timestamp;
        scan.duration = scanDuration;
        if (scan.isSuspended) {
@@ -582,12 +586,17 @@ public class AppScanStats {
    }

    static boolean recordScanRadioStart(
            int scanMode, int scannerId, AppScanStats stats, int scanWindowMs, int scanIntervalMs) {
            int scanMode,
            int scannerId,
            AppScanStats stats,
            int scanWindowMs,
            int scanIntervalMs,
            TimeProvider timeProvider) {
        synchronized (sLock) {
            if (sIsRadioStarted) {
                return false;
            }
            sRadioStartTime = SystemClock.elapsedRealtime();
            sRadioStartTime = timeProvider.elapsedRealtime();
            sRadioScanWorkSourceUtil = stats.mWorkSourceUtil;
            sRadioScanType = convertScanType(stats.getScanFromScannerId(scannerId));
            sRadioScanMode = scanMode;
@@ -598,12 +607,12 @@ public class AppScanStats {
        return true;
    }

    static boolean recordScanRadioStop() {
    static boolean recordScanRadioStop(TimeProvider timeProvider) {
        synchronized (sLock) {
            if (!sIsRadioStarted) {
                return false;
            }
            recordScanRadioDurationMetrics();
            recordScanRadioDurationMetrics(timeProvider);
            if (!Flags.bleScanAdvMetricsRedesign()) {
                sRadioStartTime = 0;
                sIsRadioStarted = false;
@@ -613,12 +622,12 @@ public class AppScanStats {
    }

    @GuardedBy("sLock")
    private static void recordScanRadioDurationMetrics() {
    private static void recordScanRadioDurationMetrics(TimeProvider timeProvider) {
        if (!sIsRadioStarted) {
            return;
        }
        MetricsLogger logger = MetricsLogger.getInstance();
        long currentTime = SystemClock.elapsedRealtime();
        long currentTime = timeProvider.elapsedRealtime();
        long radioScanDuration = currentTime - sRadioStartTime;
        double scanWeight = getScanWeight(sRadioScanMode) * 0.01;
        long weightedDuration = (long) (radioScanDuration * scanWeight);
@@ -746,14 +755,14 @@ public class AppScanStats {
        }
    }

    static void setScreenState(boolean isScreenOn) {
    static void setScreenState(boolean isScreenOn, TimeProvider timeProvider) {
        synchronized (sLock) {
            if (sIsScreenOn == isScreenOn) {
                return;
            }
            if (sIsRadioStarted) {
                recordScanRadioDurationMetrics();
                sRadioStartTime = SystemClock.elapsedRealtime();
                recordScanRadioDurationMetrics(timeProvider);
                sRadioStartTime = timeProvider.elapsedRealtime();
            }
            recordScreenOnOffMetrics(isScreenOn);
            sIsScreenOn = isScreenOn;
@@ -765,7 +774,7 @@ public class AppScanStats {
        if (scan == null || scan.isSuspended) {
            return;
        }
        scan.suspendStartTime = SystemClock.elapsedRealtime();
        scan.suspendStartTime = mTimeProvider.elapsedRealtime();
        scan.isSuspended = true;
    }

@@ -775,7 +784,7 @@ public class AppScanStats {
            return;
        }
        scan.isSuspended = false;
        stopTime = SystemClock.elapsedRealtime();
        stopTime = mTimeProvider.elapsedRealtime();
        long suspendDuration = stopTime - scan.suspendStartTime;
        scan.suspendDuration += suspendDuration;
        mTotalSuspendTime += suspendDuration;
@@ -815,7 +824,7 @@ public class AppScanStats {
            return false;
        }

        return (SystemClock.elapsedRealtime() - mLastScans.get(0).timestamp)
        return (mTimeProvider.elapsedRealtime() - mLastScans.get(0).timestamp)
                < mAdapterService.getScanQuotaWindowMillis();
    }

@@ -823,7 +832,7 @@ public class AppScanStats {
        if (!isScanning()) {
            return false;
        }
        return (SystemClock.elapsedRealtime() - mScanStartTime)
        return (mTimeProvider.elapsedRealtime() - mScanStartTime)
                >= mAdapterService.getScanTimeoutMillis();
    }

@@ -832,7 +841,7 @@ public class AppScanStats {
            return false;
        }
        LastScan lastScan = mLastScans.get(mLastScans.size() - 1);
        return ((SystemClock.elapsedRealtime() - lastScan.duration - lastScan.timestamp)
        return ((mTimeProvider.elapsedRealtime() - lastScan.duration - lastScan.timestamp)
                < LARGE_SCAN_TIME_GAP_MS);
    }

@@ -947,7 +956,7 @@ public class AppScanStats {
    @SuppressWarnings("JavaUtilDate") // TODO: b/365629730 -- prefer Instant or LocalDate
    public synchronized void dumpToString(StringBuilder sb) {
        long currentTime = System.currentTimeMillis();
        long currTime = SystemClock.elapsedRealtime();
        long currTime = mTimeProvider.elapsedRealtime();
        long scanDuration = 0;
        long suspendDuration = 0;
        long activeDuration = 0;
+42 −76
Original line number Diff line number Diff line
@@ -38,7 +38,6 @@ import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.provider.Settings;
import android.util.Log;
@@ -47,6 +46,7 @@ import android.util.SparseIntArray;
import android.view.Display;

import com.android.bluetooth.Utils;
import com.android.bluetooth.Utils.TimeProvider;
import com.android.bluetooth.btservice.AdapterService;
import com.android.bluetooth.btservice.BluetoothAdapterProxy;
import com.android.bluetooth.flags.Flags;
@@ -103,7 +103,6 @@ public class ScanManager {
    static final int MSG_REVERT_SCAN_MODE_UPGRADE = 9;
    static final int MSG_START_CONNECTING = 10;
    static final int MSG_STOP_CONNECTING = 11;
    private static final int MSG_BT_PROFILE_CONN_STATE_CHANGED = 12;
    private static final String ACTION_REFRESH_BATCHED_SCAN =
            "com.android.bluetooth.gatt.REFRESH_BATCHED_SCAN";

@@ -123,9 +122,10 @@ public class ScanManager {
    private final Context mContext;
    private final TransitionalScanHelper mScanHelper;
    private final AdapterService mAdapterService;
    private final TimeProvider mTimeProvider;
    private ScanNative mScanNative;
    private volatile ClientHandler mHandler;
    private BluetoothAdapterProxy mBluetoothAdapterProxy;
    @VisibleForTesting final ClientHandler mHandler;

    private Set<ScanClient> mRegularScanClients;
    private Set<ScanClient> mBatchClients;
@@ -160,19 +160,20 @@ public class ScanManager {
    }

    public ScanManager(
            Context context,
            TransitionalScanHelper scanHelper,
            AdapterService adapterService,
            TransitionalScanHelper scanHelper,
            BluetoothAdapterProxy bluetoothAdapterProxy,
            Looper looper) {
            Looper looper,
            TimeProvider timeProvider) {
        mRegularScanClients =
                Collections.newSetFromMap(new ConcurrentHashMap<ScanClient, Boolean>());
        mBatchClients = Collections.newSetFromMap(new ConcurrentHashMap<ScanClient, Boolean>());
        mSuspendedScanClients =
                Collections.newSetFromMap(new ConcurrentHashMap<ScanClient, Boolean>());
        mContext = context;
        mContext = adapterService;
        mScanHelper = scanHelper;
        mAdapterService = adapterService;
        mTimeProvider = timeProvider;
        mScanNative = new ScanNative(scanHelper);
        mDisplayManager = mContext.getSystemService(DisplayManager.class);
        mActivityManager = mContext.getSystemService(ActivityManager.class);
@@ -195,7 +196,7 @@ public class ScanManager {
        }
        mScreenOn = isScreenOn();
        AppScanStats.initScanRadioState();
        AppScanStats.setScreenState(mScreenOn);
        AppScanStats.setScreenState(mScreenOn, mTimeProvider);
        if (mActivityManager != null) {
            mActivityManager.addOnUidImportanceListener(
                    mUidImportanceListener, FOREGROUND_IMPORTANCE_CUTOFF);
@@ -223,15 +224,12 @@ public class ScanManager {
            mDisplayManager.unregisterDisplayListener(mDisplayListener);
        }

        if (mHandler != null) {
        // Shut down the thread
        mHandler.removeCallbacksAndMessages(null);
        Looper looper = mHandler.getLooper();
        if (looper != null) {
            looper.quitSafely();
        }
            mHandler = null;
        }

        try {
            mContext.unregisterReceiver(mLocationReceiver);
@@ -301,15 +299,7 @@ public class ScanManager {
    }

    private void sendMessage(int what, ScanClient client) {
        final ClientHandler handler = mHandler;
        if (handler == null) {
            Log.d(TAG, "sendMessage: mHandler is null.");
            return;
        }
        Message message = new Message();
        message.what = what;
        message.obj = client;
        handler.sendMessage(message);
        mHandler.obtainMessage(what, client).sendToTarget();
    }

    private boolean isFilteringSupported() {
@@ -325,7 +315,8 @@ public class ScanManager {
    }

    // Handler class that handles BLE scan operations.
    private class ClientHandler extends Handler {
    @VisibleForTesting
    class ClientHandler extends Handler {

        ClientHandler(Looper looper) {
            super(looper);
@@ -370,9 +361,6 @@ public class ScanManager {
                case MSG_STOP_CONNECTING:
                    handleClearConnectingState();
                    break;
                case MSG_BT_PROFILE_CONN_STATE_CHANGED:
                    handleProfileConnectionStateChanged(msg);
                    break;
                default:
                    // Shouldn't happen.
                    Log.e(TAG, "received an unknown message : " + msg.what);
@@ -545,7 +533,7 @@ public class ScanManager {
        }

        void handleScreenOff() {
            AppScanStats.setScreenState(false);
            AppScanStats.setScreenState(false, mTimeProvider);
            if (!mScreenOn) {
                return;
            }
@@ -880,7 +868,7 @@ public class ScanManager {
        }

        void handleScreenOn() {
            AppScanStats.setScreenState(true);
            AppScanStats.setScreenState(true, mTimeProvider);
            if (mScreenOn) {
                return;
            }
@@ -919,9 +907,7 @@ public class ScanManager {
            }
        }

        private void handleProfileConnectionStateChanged(Message msg) {
            int fromState = msg.arg1, toState = msg.arg2;
            int profile = ((Integer) msg.obj).intValue();
        private void handleProfileConnectionStateChanged(int profile, int fromState, int toState) {
            boolean updatedConnectingState =
                    updateCountersAndCheckForConnectingState(toState, fromState);
            Log.d(
@@ -1050,7 +1036,7 @@ public class ScanManager {
                    new BroadcastReceiver() {
                        @Override
                        public void onReceive(Context context, Intent intent) {
                            Log.d(TAG, "awakened up at time " + SystemClock.elapsedRealtime());
                            Log.d(TAG, "awakened up at time " + mTimeProvider.elapsedRealtime());
                            String action = intent.getAction();

                            if (action.equals(ACTION_REFRESH_BATCHED_SCAN)) {
@@ -1107,7 +1093,7 @@ public class ScanManager {
                    int scanInterval = Utils.millsToUnit(scanIntervalMs);
                    int scanPhyMask = getScanPhyMask(client.settings);
                    mNativeInterface.gattClientScan(false);
                    if (!AppScanStats.recordScanRadioStop()) {
                    if (!AppScanStats.recordScanRadioStop(mTimeProvider)) {
                        Log.w(TAG, "There is no scan radio to stop");
                    }
                    Log.d(
@@ -1139,7 +1125,8 @@ public class ScanManager {
                                    client.scannerId,
                                    client.stats,
                                    scanWindowMs,
                                    scanIntervalMs)) {
                                    scanIntervalMs,
                                    mTimeProvider)) {
                        Log.w(TAG, "Scan radio already started");
                    }
                    mLastConfiguredScanSetting = curScanSetting;
@@ -1188,7 +1175,8 @@ public class ScanManager {
                                    client.scannerId,
                                    client.stats,
                                    getScanWindowMillis(client.settings),
                                    getScanIntervalMillis(client.settings))) {
                                    getScanIntervalMillis(client.settings),
                                    mTimeProvider)) {
                        Log.w(TAG, "Scan radio already started");
                    }
                }
@@ -1382,7 +1370,7 @@ public class ScanManager {
            // Allows the alarm to be triggered within
            // [batchTriggerIntervalMillis, 1.1 * batchTriggerIntervalMillis]
            long windowLengthMillis = batchTriggerIntervalMillis / 10;
            long windowStartMillis = SystemClock.elapsedRealtime() + batchTriggerIntervalMillis;
            long windowStartMillis = mTimeProvider.elapsedRealtime() + batchTriggerIntervalMillis;
            mAlarmManager.setWindow(
                    AlarmManager.ELAPSED_REALTIME_WAKEUP,
                    windowStartMillis,
@@ -1418,7 +1406,7 @@ public class ScanManager {
            if (numRegularScanClients() == 0) {
                Log.d(TAG, "stop gattClientScanNative");
                mNativeInterface.gattClientScan(false);
                if (!AppScanStats.recordScanRadioStop()) {
                if (!AppScanStats.recordScanRadioStop(mTimeProvider)) {
                    Log.w(TAG, "There is no scan radio to stop");
                }
            }
@@ -1465,7 +1453,7 @@ public class ScanManager {
            if (numRegularScanClients() == 0) {
                Log.d(TAG, "stop gattClientScanNative");
                mNativeInterface.gattClientScan(false);
                if (!AppScanStats.recordScanRadioStop()) {
                if (!AppScanStats.recordScanRadioStop(mTimeProvider)) {
                    Log.w(TAG, "There is no scan radio to stop");
                }
            }
@@ -1604,8 +1592,7 @@ public class ScanManager {
                            if (client.stats != null) {
                                client.stats.recordTrackingHwFilterNotAvailableCountMetrics(
                                        client.scannerId,
                                        AdapterService.getAdapterService()
                                                .getTotalNumOfTrackableAdvertisements());
                                        mAdapterService.getTotalNumOfTrackableAdvertisements());
                            }
                            try {
                                mScanHelper.onScanManagerErrorCallback(
@@ -1706,8 +1693,7 @@ public class ScanManager {
                if (client.stats != null) {
                    client.stats.recordHwFilterNotAvailableCountMetrics(
                            client.scannerId,
                            AdapterService.getAdapterService()
                                    .getNumOfOffloadedScanFilterSupported());
                            mAdapterService.getNumOfOffloadedScanFilterSupported());
                }
                return true;
            }
@@ -1715,8 +1701,7 @@ public class ScanManager {
        }

        private void initFilterIndexStack() {
            int maxFiltersSupported =
                    AdapterService.getAdapterService().getNumOfOffloadedScanFilterSupported();
            int maxFiltersSupported = mAdapterService.getNumOfOffloadedScanFilterSupported();
            if (!isFilteringSupported() && mIsMsftSupported) {
                // Hardcoded minimum number of hardware adv monitor slots, because this value
                // cannot be queried from the controller for MSFT enabled devices
@@ -1928,7 +1913,7 @@ public class ScanManager {
            }
            int val = 0;
            int maxTotalTrackableAdvertisements =
                    AdapterService.getAdapterService().getTotalNumOfTrackableAdvertisements();
                    mAdapterService.getTotalNumOfTrackableAdvertisements();
            // controller based onfound onlost resources are scarce commodity; the
            // assignment of filters to num of beacons to track is configurable based
            // on hw capabilities. Apps give an intent and allocation of onfound
@@ -1955,7 +1940,7 @@ public class ScanManager {
        private boolean manageAllocationOfTrackingAdvertisement(
                int numOfTrackableAdvertisement, boolean allocate) {
            int maxTotalTrackableAdvertisements =
                    AdapterService.getAdapterService().getTotalNumOfTrackableAdvertisements();
                    mAdapterService.getTotalNumOfTrackableAdvertisements();
            synchronized (mCurUsedTrackableAdvertisementsLock) {
                int availableEntries =
                        maxTotalTrackableAdvertisements - mCurUsedTrackableAdvertisements;
@@ -2061,11 +2046,6 @@ public class ScanManager {
        }
    }

    @VisibleForTesting
    ClientHandler getClientHandler() {
        return mHandler;
    }

    @VisibleForTesting
    BatchScanParams getBatchScanParams() {
        return mBatchScanParams;
@@ -2180,12 +2160,9 @@ public class ScanManager {
        }
        Log.d(
                TAG,
                "mProfilesConnecting "
                        + mProfilesConnecting
                        + ", mProfilesConnected "
                        + mProfilesConnected
                        + ", mProfilesDisconnecting "
                        + mProfilesDisconnecting);
                ("mProfilesConnecting " + mProfilesConnecting)
                        + (", mProfilesConnected " + mProfilesConnected)
                        + (", mProfilesDisconnecting " + mProfilesDisconnecting));
        return (mProfilesConnecting > 0);
    }

@@ -2226,12 +2203,9 @@ public class ScanManager {
            }
            Log.d(
                    TAG,
                    "uid "
                            + uid
                            + " isForeground "
                            + isForeground
                            + " scanMode "
                            + getScanModeString(client.settings.getScanMode()));
                    ("uid " + uid)
                            + (" isForeground " + isForeground)
                            + (" scanMode " + getScanModeString(client.settings.getScanMode())));
        }

        if (updatedScanParams) {
@@ -2251,15 +2225,7 @@ public class ScanManager {
     */
    public void handleBluetoothProfileConnectionStateChanged(
            int profile, int fromState, int toState) {
        if (mHandler == null) {
            Log.d(TAG, "handleBluetoothProfileConnectionStateChanged: mHandler is null.");
            return;
        }
        mHandler.obtainMessage(
                        MSG_BT_PROFILE_CONN_STATE_CHANGED,
                        fromState,
                        toState,
                        Integer.valueOf(profile))
                .sendToTarget();
        mHandler.post(
                () -> mHandler.handleProfileConnectionStateChanged(profile, fromState, toState));
    }
}
+6 −6
Original line number Diff line number Diff line
@@ -16,7 +16,8 @@

package com.android.bluetooth.le_scan;

import android.content.Context;
import static com.android.bluetooth.Utils.sSystemClock;

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

@@ -66,20 +67,19 @@ public class ScanObjectsFactory {
    /**
     * Create an instance of ScanManager
     *
     * @param context a Context instance
     * @param scanHelper a TransitionalScanHelper instance
     * @param adapterService an AdapterService instance
     * @param scanHelper a TransitionalScanHelper instance
     * @param bluetoothAdapterProxy a bluetoothAdapterProxy instance
     * @param looper the looper to be used for processing messages
     * @return the created ScanManager instance
     */
    public ScanManager createScanManager(
            Context context,
            TransitionalScanHelper scanHelper,
            AdapterService adapterService,
            TransitionalScanHelper scanHelper,
            BluetoothAdapterProxy bluetoothAdapterProxy,
            Looper looper) {
        return new ScanManager(context, scanHelper, adapterService, bluetoothAdapterProxy, looper);
        return new ScanManager(
                adapterService, scanHelper, bluetoothAdapterProxy, looper, sSystemClock);
    }

    public PeriodicScanManager createPeriodicScanManager(AdapterService adapterService) {
Loading