Merge "Add anomaly detector for unoptimized bt scanning" into oc-dr1-dev am: 37da099df1
am: ba61248568
Change-Id: I2e94b72d66f26814822dbf73865e3e4cb8b38237
This commit is contained in:
@@ -35,10 +35,12 @@ import java.util.Objects;
|
||||
public class Anomaly implements Parcelable {
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef({AnomalyType.WAKE_LOCK,
|
||||
AnomalyType.WAKEUP_ALARM})
|
||||
AnomalyType.WAKEUP_ALARM,
|
||||
AnomalyType.BLUETOOTH_SCAN})
|
||||
public @interface AnomalyType {
|
||||
int WAKE_LOCK = 0;
|
||||
int WAKEUP_ALARM = 1;
|
||||
int BLUETOOTH_SCAN = 2;
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@@ -52,7 +54,8 @@ public class Anomaly implements Parcelable {
|
||||
@AnomalyType
|
||||
public static final int[] ANOMALY_TYPE_LIST =
|
||||
{AnomalyType.WAKE_LOCK,
|
||||
AnomalyType.WAKEUP_ALARM};
|
||||
AnomalyType.WAKEUP_ALARM,
|
||||
AnomalyType.BLUETOOTH_SCAN};
|
||||
|
||||
/**
|
||||
* Type of this this anomaly
|
||||
|
@@ -22,9 +22,9 @@ import android.os.BatteryStats;
|
||||
import android.os.Bundle;
|
||||
import android.os.UserManager;
|
||||
import android.support.annotation.VisibleForTesting;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.os.BatteryStatsHelper;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.utils.AsyncLoader;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -35,6 +35,8 @@ import java.util.List;
|
||||
* an empty list if there is no anomaly.
|
||||
*/
|
||||
public class AnomalyLoader extends AsyncLoader<List<Anomaly>> {
|
||||
private static final String TAG = "AnomalyLoader";
|
||||
|
||||
private static final boolean USE_FAKE_DATA = false;
|
||||
private BatteryStatsHelper mBatteryStatsHelper;
|
||||
private String mPackageName;
|
||||
@@ -108,9 +110,9 @@ public class AnomalyLoader extends AsyncLoader<List<Anomaly>> {
|
||||
List<Anomaly> generateFakeData() {
|
||||
final List<Anomaly> anomalies = new ArrayList<>();
|
||||
final Context context = getContext();
|
||||
final String packageName = "com.android.settings";
|
||||
final CharSequence displayName = "Settings";
|
||||
try {
|
||||
final String packageName = "com.android.settings";
|
||||
final CharSequence displayName = "Settings";
|
||||
final int uid = context.getPackageManager().getPackageUid(packageName, 0);
|
||||
|
||||
anomalies.add(new Anomaly.Builder()
|
||||
@@ -125,8 +127,14 @@ public class AnomalyLoader extends AsyncLoader<List<Anomaly>> {
|
||||
.setPackageName(packageName)
|
||||
.setDisplayName(displayName)
|
||||
.build());
|
||||
anomalies.add(new Anomaly.Builder()
|
||||
.setUid(uid)
|
||||
.setType(Anomaly.AnomalyType.BLUETOOTH_SCAN)
|
||||
.setPackageName(packageName)
|
||||
.setDisplayName(displayName)
|
||||
.build());
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
Log.e(TAG, "Cannot find package by name: " + packageName, e);
|
||||
}
|
||||
return anomalies;
|
||||
}
|
||||
|
@@ -23,6 +23,7 @@ import com.android.settings.fuelgauge.anomaly.action.AnomalyAction;
|
||||
import com.android.settings.fuelgauge.anomaly.action.BackgroundCheckAction;
|
||||
import com.android.settings.fuelgauge.anomaly.action.ForceStopAction;
|
||||
import com.android.settings.fuelgauge.anomaly.checker.AnomalyDetector;
|
||||
import com.android.settings.fuelgauge.anomaly.checker.BluetoothScanAnomalyDetector;
|
||||
import com.android.settings.fuelgauge.anomaly.checker.WakeLockAnomalyDetector;
|
||||
import com.android.settings.fuelgauge.anomaly.checker.WakeupAlarmAnomalyDetector;
|
||||
|
||||
@@ -56,6 +57,7 @@ public class AnomalyUtils {
|
||||
case Anomaly.AnomalyType.WAKE_LOCK:
|
||||
return new ForceStopAction(mContext);
|
||||
case Anomaly.AnomalyType.WAKEUP_ALARM:
|
||||
case Anomaly.AnomalyType.BLUETOOTH_SCAN:
|
||||
return new BackgroundCheckAction(mContext);
|
||||
default:
|
||||
return null;
|
||||
@@ -74,6 +76,8 @@ public class AnomalyUtils {
|
||||
return new WakeLockAnomalyDetector(mContext);
|
||||
case Anomaly.AnomalyType.WAKEUP_ALARM:
|
||||
return new WakeupAlarmAnomalyDetector(mContext);
|
||||
case Anomaly.AnomalyType.BLUETOOTH_SCAN:
|
||||
return new BluetoothScanAnomalyDetector(mContext);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.fuelgauge.anomaly.checker;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.BatteryStats;
|
||||
import android.os.SystemClock;
|
||||
import android.support.annotation.VisibleForTesting;
|
||||
import android.text.format.DateUtils;
|
||||
import android.util.ArrayMap;
|
||||
|
||||
import com.android.internal.os.BatterySipper;
|
||||
import com.android.internal.os.BatteryStatsHelper;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.fuelgauge.BatteryUtils;
|
||||
import com.android.settings.fuelgauge.anomaly.Anomaly;
|
||||
import com.android.settings.fuelgauge.anomaly.AnomalyDetectionPolicy;
|
||||
import com.android.settings.fuelgauge.anomaly.AnomalyUtils;
|
||||
import com.android.settings.fuelgauge.anomaly.action.AnomalyAction;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Check whether apps have unoptimized bluetooth scanning in the background
|
||||
*/
|
||||
public class BluetoothScanAnomalyDetector implements AnomalyDetector {
|
||||
private static final String TAG = "BluetoothScanAnomalyDetector";
|
||||
@VisibleForTesting
|
||||
BatteryUtils mBatteryUtils;
|
||||
@VisibleForTesting
|
||||
AnomalyAction mAnomalyAction;
|
||||
private long mBluetoothScanningThreshold;
|
||||
private Context mContext;
|
||||
|
||||
public BluetoothScanAnomalyDetector(Context context) {
|
||||
this(context, new AnomalyDetectionPolicy(context));
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
BluetoothScanAnomalyDetector(Context context, AnomalyDetectionPolicy policy) {
|
||||
mContext = context;
|
||||
mBatteryUtils = BatteryUtils.getInstance(context);
|
||||
mAnomalyAction = AnomalyUtils.getInstance(context).getAnomalyAction(
|
||||
Anomaly.AnomalyType.BLUETOOTH_SCAN);
|
||||
//TODO(b/36921532): hook up it to AnomalyDectionPolicy
|
||||
mBluetoothScanningThreshold = 30 * DateUtils.MINUTE_IN_MILLIS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Anomaly> detectAnomalies(BatteryStatsHelper batteryStatsHelper) {
|
||||
// Detect all apps if targetPackageName is null
|
||||
return detectAnomalies(batteryStatsHelper, null /* targetPackageName */);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Anomaly> detectAnomalies(BatteryStatsHelper batteryStatsHelper,
|
||||
String targetPackageName) {
|
||||
final List<BatterySipper> batterySippers = batteryStatsHelper.getUsageList();
|
||||
final List<Anomaly> anomalies = new ArrayList<>();
|
||||
final int targetUid = mBatteryUtils.getPackageUid(targetPackageName);
|
||||
final long elapsedRealtimeMs = SystemClock.elapsedRealtime();
|
||||
|
||||
for (int i = 0, size = batterySippers.size(); i < size; i++) {
|
||||
final BatterySipper sipper = batterySippers.get(i);
|
||||
final BatteryStats.Uid uid = sipper.uidObj;
|
||||
if (uid == null
|
||||
|| mBatteryUtils.shouldHideSipper(sipper)
|
||||
|| (targetUid != BatteryUtils.UID_NULL && targetUid != uid.getUid())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final long bluetoothTimeMs = getBluetoothUnoptimizedBgTimeMs(uid, elapsedRealtimeMs);
|
||||
if (bluetoothTimeMs > mBluetoothScanningThreshold) {
|
||||
final String packageName = mBatteryUtils.getPackageName(uid.getUid());
|
||||
final CharSequence displayName = Utils.getApplicationLabel(mContext,
|
||||
packageName);
|
||||
|
||||
Anomaly anomaly = new Anomaly.Builder()
|
||||
.setUid(uid.getUid())
|
||||
.setType(Anomaly.AnomalyType.BLUETOOTH_SCAN)
|
||||
.setDisplayName(displayName)
|
||||
.setPackageName(packageName)
|
||||
.build();
|
||||
|
||||
if (mAnomalyAction.isActionActive(anomaly)) {
|
||||
anomalies.add(anomaly);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return anomalies;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public long getBluetoothUnoptimizedBgTimeMs(BatteryStats.Uid uid, long elapsedRealtimeMs) {
|
||||
BatteryStats.Timer timer = uid.getBluetoothUnoptimizedScanBackgroundTimer();
|
||||
|
||||
return timer != null ? timer.getTotalDurationMsLocked(elapsedRealtimeMs) : 0;
|
||||
}
|
||||
|
||||
}
|
@@ -65,7 +65,8 @@ public class WakeLockAnomalyDetector implements AnomalyDetector {
|
||||
|
||||
@Override
|
||||
public List<Anomaly> detectAnomalies(BatteryStatsHelper batteryStatsHelper) {
|
||||
return detectAnomalies(batteryStatsHelper, null);
|
||||
// Detect all apps if targetPackageName is null
|
||||
return detectAnomalies(batteryStatsHelper, null /* targetPackageName */);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -61,7 +61,8 @@ public class WakeupAlarmAnomalyDetector implements AnomalyDetector {
|
||||
|
||||
@Override
|
||||
public List<Anomaly> detectAnomalies(BatteryStatsHelper batteryStatsHelper) {
|
||||
return detectAnomalies(batteryStatsHelper, null);
|
||||
// Detect all apps if targetPackageName is null
|
||||
return detectAnomalies(batteryStatsHelper, null /* targetPackageName */);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
Reference in New Issue
Block a user