<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"/>
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;
@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) {
}
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(
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;
// 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;
}
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;
private Integer curUsedTrackableAdvertisements;
private GattService mService;
+ private IBatteryStats mBatteryStats;
private BroadcastReceiver mBatchAlarmReceiver;
private boolean mBatchAlarmReceiverRegistered;
private ScanNative mScanNative;
}
void start() {
+ mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService("batterystats"));
HandlerThread thread = new HandlerThread("BluetoothScanManager");
thread.start();
mHandler = new ClientHandler(thread.getLooper());
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);
if (!mScanNative.isOpportunisticScanClient(client)) {
mScanNative.configureRegularScanParams();
}
+
+ // Update BatteryStats with this workload.
+ try {
+ mBatteryStats.noteBleScanStopped(client.workSource);
+ } catch (RemoteException e) {
+ /* ignore */
+ }
} else {
mScanNative.stopBatchScan(client);
}
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) {