OSDN Git Service

Use the incoming WorkSource to notify batterystats of BLE scans
authorAdam Lesinski <adamlesinski@google.com>
Mon, 22 Aug 2016 18:26:16 +0000 (11:26 -0700)
committerAdam Lesinski <adamlesinski@google.com>
Mon, 22 Aug 2016 18:44:34 +0000 (11:44 -0700)
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: I15dd7c912320552323aaf9d713b4bb3224ffffec

AndroidManifest.xml
src/com/android/bluetooth/gatt/GattService.java
src/com/android/bluetooth/gatt/ScanClient.java
src/com/android/bluetooth/gatt/ScanManager.java

index 711542c..ea6e39b 100644 (file)
@@ -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"/>
index 0ef6079..1e5c01f 100644 (file)
@@ -37,10 +37,12 @@ import android.bluetooth.le.ScanRecord;
 import android.bluetooth.le.ScanResult;
 import android.bluetooth.le.ScanSettings;
 import android.content.Intent;
+import android.os.Binder;
 import android.os.IBinder;
 import android.os.ParcelUuid;
 import android.os.RemoteException;
 import android.os.SystemClock;
+import android.os.WorkSource;
 import android.provider.Settings;
 import android.util.Log;
 
@@ -316,10 +318,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) {
@@ -1207,14 +1211,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(
index b7bfd33..a620436 100644 (file)
@@ -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,36 +44,47 @@ 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 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;
     }
 
index 2475306..a885a72 100644 (file)
@@ -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;
@@ -81,6 +83,7 @@ public class ScanManager {
 
     private Integer curUsedTrackableAdvertisements;
     private GattService mService;
+    private IBatteryStats mBatteryStats;
     private BroadcastReceiver mBatchAlarmReceiver;
     private boolean mBatchAlarmReceiverRegistered;
     private ScanNative mScanNative;
@@ -100,6 +103,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());
@@ -242,12 +246,25 @@ public class ScanManager {
                         mHandler.sendMessageDelayed(msg, SCAN_TIMEOUT_MS);
                     }
                 }
+
+                // 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);
 
@@ -258,6 +275,13 @@ public class ScanManager {
                 if (!mScanNative.isOpportunisticScanClient(client)) {
                     mScanNative.configureRegularScanParams();
                 }
+
+                // Update BatteryStats with this workload.
+                try {
+                    mBatteryStats.noteBleScanStopped(client.workSource);
+                } catch (RemoteException e) {
+                    /* ignore */
+                }
             } else {
                 mScanNative.stopBatchScan(client);
             }
@@ -632,7 +656,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) {