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

Commit 1ff40339 authored by Ajay Panicker's avatar Ajay Panicker
Browse files

Move Bluetooth battery stats tracking (2/2)

Move Bluetooth battery stats tracking to AppScanStats for a more
unified tracking system.

Bug: 37720787
Test: cts-tradefed run cts-dev -m CtsIncidentHostTestCases -t com.android.server.cts.BatteryStatsValidationTest#testBleScans
      Perform BLE scan and check battery stats
Change-Id: I6129a83d275c7d72edc6abfc5cc72641adde8767
parent aae5bbe4
Loading
Loading
Loading
Loading
+29 −1
Original line number Diff line number Diff line
@@ -16,6 +16,11 @@
package com.android.bluetooth.gatt;

import android.bluetooth.le.ScanSettings;
import android.os.Binder;
import android.os.WorkSource;
import android.os.ServiceManager;
import android.os.RemoteException;
import com.android.internal.app.IBatteryStats;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
@@ -38,6 +43,9 @@ import com.android.bluetooth.btservice.BluetoothProto;
    /* GattService is needed to add scan event protos to be dumped later */
    GattService gattService;

    /* Battery stats is used to keep track of scans and result stats */
    IBatteryStats batteryStats;

    class LastScan {
        long duration;
        long timestamp;
@@ -70,6 +78,7 @@ import com.android.bluetooth.btservice.BluetoothProto;
    static final int SCAN_TIMEOUT_MS = 30 * 60 * 1000;

    String appName;
    WorkSource workSource; // Used for BatteryStats
    int scansStarted = 0;
    int scansStopped = 0;
    boolean isScanning = false;
@@ -82,10 +91,17 @@ import com.android.bluetooth.btservice.BluetoothProto;
    long stopTime = 0;
    int results = 0;

    public AppScanStats(String name, ContextMap map, GattService service) {
    public AppScanStats(String name, WorkSource source, ContextMap map, GattService service) {
        appName = name;
        contextMap = map;
        gattService = service;
        batteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService("batterystats"));

        if (source == null) {
            // Bill the caller if the work source isn't passed through
            source = new WorkSource(Binder.getCallingUid(), appName);
        }
        workSource = source;
    }

    synchronized void addResult() {
@@ -116,6 +132,12 @@ import com.android.bluetooth.btservice.BluetoothProto;
        scanEvent.setEventTimeMillis(System.currentTimeMillis());
        scanEvent.setInitiator(truncateAppName(appName));
        gattService.addScanEvent(scanEvent);

        try {
            batteryStats.noteBleScanStarted(workSource);
        } catch (RemoteException e) {
            /* ignore */
        }
    }

    synchronized void recordScanStop() {
@@ -144,6 +166,12 @@ import com.android.bluetooth.btservice.BluetoothProto;
        scanEvent.setEventTimeMillis(System.currentTimeMillis());
        scanEvent.setInitiator(truncateAppName(appName));
        gattService.addScanEvent(scanEvent);

        try {
            batteryStats.noteBleScanStopped(workSource);
        } catch (RemoteException e) {
            /* ignore */
        }
    }

    synchronized void setScanTimeout() {
+3 −2
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import android.os.IBinder;
import android.os.IBinder.DeathRecipient;
import android.os.IInterface;
import android.os.RemoteException;
import android.os.WorkSource;
import android.util.Log;
import java.util.ArrayList;
import java.util.HashSet;
@@ -144,7 +145,7 @@ import com.android.bluetooth.btservice.BluetoothProto;
    /**
     * Add an entry to the application context list.
     */
    void add(UUID uuid, T callback, GattService service) {
    void add(UUID uuid, WorkSource workSource, T callback, GattService service) {
        String appName = service.getPackageManager().getNameForUid(
                             Binder.getCallingUid());
        if (appName == null) {
@@ -154,7 +155,7 @@ import com.android.bluetooth.btservice.BluetoothProto;
        synchronized (mApps) {
            AppScanStats appScanStats = mAppScanStats.get(appName);
            if (appScanStats == null) {
                appScanStats = new AppScanStats(appName, this, service);
                appScanStats = new AppScanStats(appName, workSource, this, service);
                mAppScanStats.put(appName, appScanStats);
            }
            mApps.add(new App(uuid, callback, appName, appScanStats));
+16 −21
Original line number Diff line number Diff line
@@ -350,10 +350,10 @@ public class GattService extends ProfileService {
            service.unregisterClient(clientIf);
        }

        public void registerScanner(IScannerCallback callback) {
        public void registerScanner(IScannerCallback callback, WorkSource workSource) {
            GattService service = getService();
            if (service == null) return;
            service.registerScanner(callback);
            service.registerScanner(callback, workSource);
        }

        public void unregisterScanner(int scannerId) {
@@ -363,13 +363,11 @@ public class GattService extends ProfileService {
        }

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

        public void stopScan(int scannerId) {
@@ -1417,12 +1415,17 @@ public class GattService extends ProfileService {
        return deviceList;
    }

    void registerScanner(IScannerCallback callback) {
    void registerScanner(IScannerCallback callback, WorkSource workSource) {
        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");

        UUID uuid = UUID.randomUUID();
        if (DBG) Log.d(TAG, "registerScanner() - UUID=" + uuid);
        mScannerMap.add(uuid, callback, this);

        if (workSource != null) {
            enforceImpersonatationPermission();
        }

        mScannerMap.add(uuid, workSource, callback, this);
        mScanManager.registerScanner(uuid);
    }

@@ -1434,22 +1437,14 @@ public class GattService extends ProfileService {
        mScanManager.unregisterScanner(scannerId);
    }

    void startScan(int scannerId, ScanSettings settings,
            List<ScanFilter> filters, WorkSource workSource,
    void startScan(int scannerId, ScanSettings settings, List<ScanFilter> filters,
            List<List<ResultStorageDescriptor>> storages, String callingPackage) {
        if (DBG) Log.d(TAG, "start scan with filters");
        enforceAdminPermission();
        if (needsPrivilegedPermissionForScan(settings)) {
            enforcePrivilegedPermission();
        }
        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(scannerId, settings, filters, workSource,
                storages);
        final ScanClient scanClient = new ScanClient(scannerId, settings, filters, storages);
        scanClient.hasLocationPermission = Utils.checkCallerHasLocationPermission(this, mAppOps,
                callingPackage);
        scanClient.hasPeersMacAddressPermission = Utils.checkCallerHasPeersMacAddressPermission(
@@ -1589,7 +1584,7 @@ public class GattService extends ProfileService {
        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");

        if (DBG) Log.d(TAG, "registerClient() - UUID=" + uuid);
        mClientMap.add(uuid, callback, this);
        mClientMap.add(uuid, null, callback, this);
        gattClientRegisterAppNative(uuid.getLeastSignificantBits(),
                                    uuid.getMostSignificantBits());
    }
@@ -2128,7 +2123,7 @@ public class GattService extends ProfileService {
        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");

        if (DBG) Log.d(TAG, "registerServer() - UUID=" + uuid);
        mServerMap.add(uuid, callback, this);
        mServerMap.add(uuid, null, callback, this);
        gattServerRegisterAppNative(uuid.getLeastSignificantBits(),
                                    uuid.getMostSignificantBits());
    }
+7 −19
Original line number Diff line number Diff line
@@ -19,7 +19,6 @@ 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,46 +42,35 @@ 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;

    AppScanStats stats = null;

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

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

    ScanClient(int scannerId, UUID[] uuids) {
        this(scannerId, uuids, DEFAULT_SCAN_SETTINGS, null, null, null);
        this(scannerId, uuids, DEFAULT_SCAN_SETTINGS, null, null);
    }

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

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

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

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

+0 −20
Original line number Diff line number Diff line
@@ -37,7 +37,6 @@ 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.Collections;
@@ -83,7 +82,6 @@ public class ScanManager {

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

    void start() {
        mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService("batterystats"));
        HandlerThread thread = new HandlerThread("BluetoothScanManager");
        thread.start();
        mHandler = new ClientHandler(thread.getLooper());
@@ -254,13 +251,6 @@ public class ScanManager {
                        mHandler.sendMessageDelayed(msg, AppScanStats.SCAN_TIMEOUT_MS);
                    }
                }

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

@@ -269,16 +259,6 @@ public class ScanManager {
            if (client == null) return;

            if (mRegularScanClients.contains(client)) {
                // Update BatteryStats with this workload.
                try {
                    // The ScanClient passed in just holds the scannerId. We retrieve the real
                    // client, which may have workSource set.
                    ScanClient workClient = mScanNative.getRegularScanClient(client.scannerId);
                    if (workClient != null) mBatteryStats.noteBleScanStopped(workClient.workSource);
                } catch (RemoteException e) {
                    /* ignore */
                }

                mScanNative.stopRegularScan(client);

                if (mScanNative.numRegularScanClients() == 0) {