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

Commit 44f6d970 authored by Adam Lesinski's avatar Adam Lesinski Committed by Andre Eisenbach
Browse files

Use the incoming WorkSource to notify batterystats of BLE scans

BatteryStats is going to start tracking bluetooth scanning, so
we start by passing along the WorkSource we were given (or we created
if none was specified).

This is only done for BLE scanning at the moment, and only for regular scans.
Batched scans will also need to be considered.
Bug:22718669

Change-Id: I3ff042d6c344f13b600602c5966aef60b4587916
parent d8f88f77
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -64,6 +64,7 @@
    <uses-permission android:name="android.permission.DEVICE_POWER" />
    <uses-permission android:name="android.permission.REAL_GET_TASKS" />
    <uses-permission android:name="android.permission.MODIFY_AUDIO_ROUTING" />
    <uses-permission android:name="android.permission.UPDATE_DEVICE_STATS" />

    <!-- For PBAP Owner Vcard Info -->
    <uses-permission android:name="android.permission.READ_PROFILE"/>
+23 −6
Original line number Diff line number Diff line
@@ -39,7 +39,7 @@ import android.os.IBinder;
import android.os.ParcelUuid;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.UserHandle;
import android.os.WorkSource;
import android.provider.Settings;
import android.util.Log;

@@ -314,10 +314,12 @@ public class GattService extends ProfileService {

        @Override
        public void startScan(int appIf, boolean isServer, ScanSettings settings,
                List<ScanFilter> filters, List storages, String callingPackage) {
                List<ScanFilter> filters, WorkSource workSource, List storages,
                String callingPackage) {
            GattService service = getService();
            if (service == null) return;
            service.startScan(appIf, isServer, settings, filters, storages, callingPackage);
            service.startScan(appIf, isServer, settings, filters, workSource, storages,
                    callingPackage);
        }

        public void stopScan(int appIf, boolean isServer) {
@@ -1376,14 +1378,21 @@ public class GattService extends ProfileService {
    }

    void startScan(int appIf, boolean isServer, ScanSettings settings,
            List<ScanFilter> filters, List<List<ResultStorageDescriptor>> storages,
            String callingPackage) {
            List<ScanFilter> filters, WorkSource workSource,
            List<List<ResultStorageDescriptor>> storages, String callingPackage) {
        if (DBG) Log.d(TAG, "start scan with filters");
        enforceAdminPermission();
        if (needsPrivilegedPermissionForScan(settings)) {
            enforcePrivilegedPermission();
        }
        final ScanClient scanClient = new ScanClient(appIf, isServer, settings, filters, storages);
        if (workSource != null) {
            enforceImpersonatationPermission();
        } else {
            // Blame the caller if the work source is unspecified.
            workSource = new WorkSource(Binder.getCallingUid(), callingPackage);
        }
        final ScanClient scanClient = new ScanClient(appIf, isServer, settings, filters, workSource,
                storages);
        scanClient.hasLocationPermission = Utils.checkCallerHasLocationPermission(this, mAppOps,
                callingPackage);
        scanClient.hasPeersMacAddressPermission = Utils.checkCallerHasPeersMacAddressPermission(
@@ -2168,6 +2177,14 @@ public class GattService extends ProfileService {
            "Need BLUETOOTH_PRIVILEGED permission");
    }

    // Enforce caller has UPDATE_DEVICE_STATS permission, which allows the caller to blame other
    // apps for Bluetooth usage. A {@link SecurityException} will be thrown if the caller app does
    // not have UPDATE_DEVICE_STATS permission.
    private void enforceImpersonatationPermission() {
        enforceCallingOrSelfPermission(android.Manifest.permission.UPDATE_DEVICE_STATS,
                "Need UPDATE_DEVICE_STATS permission");
    }

    private void continueSearch(int connId, int status) throws RemoteException {

        // Search is complete when there was error, or nothing more to process
+17 −5
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.bluetooth.gatt;
import android.bluetooth.le.ResultStorageDescriptor;
import android.bluetooth.le.ScanFilter;
import android.bluetooth.le.ScanSettings;
import android.os.WorkSource;

import java.util.List;
import java.util.Objects;
@@ -43,34 +44,45 @@ import java.util.UUID;
    // Pre-M apps are allowed to get scan results even if location is disabled
    boolean legacyForegroundApp;

    // Who is responsible for this scan.
    WorkSource workSource;

    private static final ScanSettings DEFAULT_SCAN_SETTINGS = new ScanSettings.Builder()
            .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).build();

    ScanClient(int appIf, boolean isServer) {
        this(appIf, isServer, new UUID[0], DEFAULT_SCAN_SETTINGS, null, null);
        this(appIf, isServer, new UUID[0], DEFAULT_SCAN_SETTINGS, null, null, null);
    }

    ScanClient(int appIf, boolean isServer, UUID[] uuids) {
        this(appIf, isServer, uuids, DEFAULT_SCAN_SETTINGS, null, null);
        this(appIf, isServer, uuids, DEFAULT_SCAN_SETTINGS, null, null, null);
    }

    ScanClient(int appIf, boolean isServer, ScanSettings settings,
            List<ScanFilter> filters) {
        this(appIf, isServer, new UUID[0], settings, filters, null);
        this(appIf, isServer, new UUID[0], settings, filters, null, null);
    }

    ScanClient(int appIf, boolean isServer, ScanSettings settings,
            List<ScanFilter> filters, List<List<ResultStorageDescriptor>> storages) {
        this(appIf, isServer, new UUID[0], settings, filters, storages);
        this(appIf, isServer, new UUID[0], settings, filters, null, storages);
    }

    ScanClient(int appIf, boolean isServer, ScanSettings settings,
               List<ScanFilter> filters, WorkSource workSource,
               List<List<ResultStorageDescriptor>> storages) {
        this(appIf, isServer, new UUID[0], settings, filters, workSource, storages);
    }

    private ScanClient(int appIf, boolean isServer, UUID[] uuids, ScanSettings settings,
            List<ScanFilter> filters, List<List<ResultStorageDescriptor>> storages) {
            List<ScanFilter> filters, WorkSource workSource,
            List<List<ResultStorageDescriptor>> storages) {
        this.clientIf = appIf;
        this.isServer = isServer;
        this.uuids = uuids;
        this.settings = settings;
        this.filters = filters;
        this.workSource = workSource;
        this.storages = storages;
    }

+24 −1
Original line number Diff line number Diff line
@@ -31,11 +31,13 @@ import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
import android.util.Log;

import com.android.bluetooth.Utils;
import com.android.bluetooth.btservice.AdapterService;
import com.android.internal.app.IBatteryStats;

import java.util.ArrayDeque;
import java.util.Deque;
@@ -77,6 +79,7 @@ public class ScanManager {

    private Integer curUsedTrackableAdvertisements;
    private GattService mService;
    private IBatteryStats mBatteryStats;
    private BroadcastReceiver mBatchAlarmReceiver;
    private boolean mBatchAlarmReceiverRegistered;
    private ScanNative mScanNative;
@@ -96,6 +99,7 @@ public class ScanManager {
    }

    void start() {
        mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService("batterystats"));
        HandlerThread thread = new HandlerThread("BluetoothScanManager");
        thread.start();
        mHandler = new ClientHandler(thread.getLooper());
@@ -217,17 +221,37 @@ public class ScanManager {
                if (!mScanNative.isOpportunisticScanClient(client)) {
                    mScanNative.configureRegularScanParams();
                }

                // Update BatteryStats with this workload.
                try {
                    mBatteryStats.noteBleScanStarted(client.workSource);
                } catch (RemoteException e) {
                    /* ignore */
                }
            }
        }

        void handleStopScan(ScanClient client) {
            Utils.enforceAdminPermission(mService);
            if (client == null) return;

            // The ScanClient passed in just holds the clientIf. We retrieve the real client,
            // which may have workSource set.
            client = mScanNative.getClient(client.clientIf);
            if (client == null) return;

            if (mRegularScanClients.contains(client)) {
                mScanNative.stopRegularScan(client);
                if (!mScanNative.isOpportunisticScanClient(client)) {
                    mScanNative.configureRegularScanParams();
                }

                // Update BatteryStats with this workload.
                try {
                    mBatteryStats.noteBleScanStopped(client.workSource);
                } catch (RemoteException e) {
                    /* ignore */
                }
            } else {
                mScanNative.stopBatchScan(client);
            }
@@ -598,7 +622,6 @@ public class ScanManager {

        void stopRegularScan(ScanClient client) {
            // Remove scan filters and recycle filter indices.
            client = getClient(client.clientIf);
            if (client == null) return;
            int deliveryMode = getDeliveryMode(client);
            if (deliveryMode == DELIVERY_MODE_ON_FOUND_LOST) {