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

Commit 2d8d8183 authored by Adam Lesinski's avatar Adam Lesinski
Browse files

Add WorkSource to BLE scanning API

This will allow apps that do work on behalf of others to correctly blame
those apps for the power implications of BLE scanning.

Bug:22718669
Change-Id: I1cbca8cf7bbe1ec5b804228f466fd9dd6fc68183
parent 3d98b602
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import android.bluetooth.le.ScanFilter;
import android.bluetooth.le.ScanSettings;
import android.bluetooth.le.ResultStorageDescriptor;
import android.os.ParcelUuid;
import android.os.WorkSource;

import android.bluetooth.IBluetoothGattCallback;
import android.bluetooth.IBluetoothGattServerCallback;
@@ -36,8 +37,8 @@ interface IBluetoothGatt {
    List<BluetoothDevice> getDevicesMatchingConnectionStates(in int[] states);

    void startScan(in int appIf, in boolean isServer, in ScanSettings settings,
                   in List<ScanFilter> filters,
                   in List scanStorages, in String callingPackage);
                   in List<ScanFilter> filters, in WorkSource workSource, in List scanStorages,
                   in String callingPackage);
    void stopScan(in int appIf, in boolean isServer);
    void flushPendingBatchResults(in int appIf, in boolean isServer);
    void startMultiAdvertising(in int appIf,
+53 −11
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import android.os.Handler;
import android.os.Looper;
import android.os.ParcelUuid;
import android.os.RemoteException;
import android.os.WorkSource;
import android.util.Log;

import java.util.ArrayList;
@@ -89,9 +90,6 @@ public final class BluetoothLeScanner {
     */
    @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
    public void startScan(final ScanCallback callback) {
        if (callback == null) {
            throw new IllegalArgumentException("callback is null");
        }
        startScan(null, new ScanSettings.Builder().build(), callback);
    }

@@ -112,14 +110,53 @@ public final class BluetoothLeScanner {
    @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
    public void startScan(List<ScanFilter> filters, ScanSettings settings,
            final ScanCallback callback) {
        startScan(filters, settings, callback, null);
        startScan(filters, settings, null, callback, null);
    }

    /**
     * Start Bluetooth LE scan. Same as {@link #startScan(ScanCallback)} but allows the caller to
     * specify on behalf of which application(s) the work is being done.
     *
     * @param workSource {@link WorkSource} identifying the application(s) for which to blame for
     *                   the scan.
     * @param callback Callback used to deliver scan results.
     * @hide
     */
    @SystemApi
    @RequiresPermission(allOf = {
            Manifest.permission.BLUETOOTH_ADMIN, Manifest.permission.UPDATE_DEVICE_STATS })
    public void startScanFromSource(final WorkSource workSource, final ScanCallback callback) {
        startScanFromSource(null, new ScanSettings.Builder().build(), workSource, callback);
    }

    /**
     * Start Bluetooth LE scan. Same as {@link #startScan(List, ScanSettings, ScanCallback)} but
     * allows the caller to specify on behalf of which application(s) the work is being done.
     *
     * @param filters {@link ScanFilter}s for finding exact BLE devices.
     * @param settings Settings for the scan.
     * @param workSource {@link WorkSource} identifying the application(s) for which to blame for
     *                   the scan.
     * @param callback Callback used to deliver scan results.
     * @hide
     */
    @SystemApi
    @RequiresPermission(allOf = {
            Manifest.permission.BLUETOOTH_ADMIN, Manifest.permission.UPDATE_DEVICE_STATS })
    public void startScanFromSource(List<ScanFilter> filters, ScanSettings settings,
                                    final WorkSource workSource, final ScanCallback callback) {
        startScan(filters, settings, workSource, callback, null);
    }

    private void startScan(List<ScanFilter> filters, ScanSettings settings,
            final ScanCallback callback, List<List<ResultStorageDescriptor>> resultStorages) {
                           final WorkSource workSource, final ScanCallback callback,
                           List<List<ResultStorageDescriptor>> resultStorages) {
        BluetoothLeUtils.checkAdapterStateOn(mBluetoothAdapter);
        if (settings == null || callback == null) {
            throw new IllegalArgumentException("settings or callback is null");
        if (callback == null) {
            throw new IllegalArgumentException("callback is null");
        }
        if (settings == null) {
            throw new IllegalArgumentException("settings is null");
        }
        synchronized (mLeScanClients) {
            if (mLeScanClients.containsKey(callback)) {
@@ -152,7 +189,7 @@ public final class BluetoothLeScanner {
                return;
            }
            BleScanCallbackWrapper wrapper = new BleScanCallbackWrapper(gatt, filters,
                    settings, callback, resultStorages);
                    settings, workSource, callback, resultStorages);
            wrapper.startRegisteration();
        }
    }
@@ -215,7 +252,7 @@ public final class BluetoothLeScanner {
            scanFilters.add(filter.getFilter());
            scanStorages.add(filter.getStorageDescriptors());
        }
        startScan(scanFilters, settings, callback, scanStorages);
        startScan(scanFilters, settings, null, callback, scanStorages);
    }

    /**
@@ -235,6 +272,7 @@ public final class BluetoothLeScanner {

        private final ScanCallback mScanCallback;
        private final List<ScanFilter> mFilters;
        private final WorkSource mWorkSource;
        private ScanSettings mSettings;
        private IBluetoothGatt mBluetoothGatt;
        private List<List<ResultStorageDescriptor>> mResultStorages;
@@ -246,10 +284,12 @@ public final class BluetoothLeScanner {

        public BleScanCallbackWrapper(IBluetoothGatt bluetoothGatt,
                List<ScanFilter> filters, ScanSettings settings,
                ScanCallback scanCallback, List<List<ResultStorageDescriptor>> resultStorages) {
                WorkSource workSource, ScanCallback scanCallback,
                List<List<ResultStorageDescriptor>> resultStorages) {
            mBluetoothGatt = bluetoothGatt;
            mFilters = filters;
            mSettings = settings;
            mWorkSource = workSource;
            mScanCallback = scanCallback;
            mClientIf = 0;
            mResultStorages = resultStorages;
@@ -322,7 +362,9 @@ public final class BluetoothLeScanner {
                    mClientIf = clientIf;
                    try {
                        mBluetoothGatt.startScan(mClientIf, false, mSettings, mFilters,
                                mResultStorages, ActivityThread.currentOpPackageName());
                                mWorkSource, mResultStorages,
                                ActivityThread.currentOpPackageName());

                    } catch (RemoteException e) {
                        Log.e(TAG, "fail to start le scan: " + e);
                        mClientIf = -1;