Update wakeup anomaly to exclude blacklisted wakeups.

Also disables all anomalies out of the box.

Provides the ability to ignore certain wakeups if blacklisted in
AnomalyDetectionPolicy. Compares each wakeup to the blacklist and
if it exists, does not include it in the count used to compare against
the threshold.

Change-Id: I4ef548bd0952be5f0d4e36df5698f287839d0704
Fixes: 67000019
Test: robotests
This commit is contained in:
Andrew Sapperstein
2017-10-05 18:19:32 -07:00
parent aa410eba1d
commit e063427d0b
5 changed files with 117 additions and 24 deletions

View File

@@ -17,6 +17,7 @@
package com.android.settings.fuelgauge.anomaly;
import android.content.Context;
import android.net.Uri;
import android.provider.Settings;
import android.support.annotation.VisibleForTesting;
import android.text.format.DateUtils;
@@ -25,6 +26,10 @@ import android.util.Log;
import com.android.settings.wrapper.KeyValueListParserWrapper;
import java.util.Arrays;
import java.util.Set;
import java.util.stream.Collectors;
/**
* Class to store the policy for anomaly detection, which comes from
* {@link android.provider.Settings.Global}
@@ -45,6 +50,8 @@ public class AnomalyDetectionPolicy {
@VisibleForTesting
static final String KEY_WAKEUP_ALARM_THRESHOLD = "wakeup_alarm_threshold";
@VisibleForTesting
static final String KEY_WAKEUP_BLACKLISTED_TAGS = "wakeup_blacklisted_tags";
@VisibleForTesting
static final String KEY_BLUETOOTH_SCAN_THRESHOLD = "bluetooth_scan_threshold";
/**
@@ -95,6 +102,14 @@ public class AnomalyDetectionPolicy {
*/
public final long wakeupAlarmThreshold;
/**
* Array of blacklisted wakeups, by tag.
*
* @see Settings.Global#ANOMALY_DETECTION_CONSTANTS
* @see #KEY_WAKEUP_BLACKLISTED_TAGS
*/
public final Set<String> wakeupBlacklistedTags;
/**
* Threshold for bluetooth unoptimized scanning time in milli seconds
*
@@ -121,15 +136,18 @@ public class AnomalyDetectionPolicy {
Log.e(TAG, "Bad anomaly detection constants");
}
anomalyDetectionEnabled = mParserWrapper.getBoolean(KEY_ANOMALY_DETECTION_ENABLED, true);
wakeLockDetectionEnabled = mParserWrapper.getBoolean(KEY_WAKELOCK_DETECTION_ENABLED, true);
wakeupAlarmDetectionEnabled = mParserWrapper.getBoolean(KEY_WAKEUP_ALARM_DETECTION_ENABLED,
false);
anomalyDetectionEnabled =
mParserWrapper.getBoolean(KEY_ANOMALY_DETECTION_ENABLED, false);
wakeLockDetectionEnabled =
mParserWrapper.getBoolean(KEY_WAKELOCK_DETECTION_ENABLED,false);
wakeupAlarmDetectionEnabled =
mParserWrapper.getBoolean(KEY_WAKEUP_ALARM_DETECTION_ENABLED,false);
bluetoothScanDetectionEnabled = mParserWrapper.getBoolean(
KEY_BLUETOOTH_SCAN_DETECTION_ENABLED, true);
KEY_BLUETOOTH_SCAN_DETECTION_ENABLED, false);
wakeLockThreshold = mParserWrapper.getLong(KEY_WAKELOCK_THRESHOLD,
DateUtils.HOUR_IN_MILLIS);
wakeupAlarmThreshold = mParserWrapper.getLong(KEY_WAKEUP_ALARM_THRESHOLD, 60);
wakeupAlarmThreshold = mParserWrapper.getLong(KEY_WAKEUP_ALARM_THRESHOLD, 10);
wakeupBlacklistedTags = parseStringSet(KEY_WAKEUP_BLACKLISTED_TAGS, null);
bluetoothScanThreshold = mParserWrapper.getLong(KEY_BLUETOOTH_SCAN_THRESHOLD,
30 * DateUtils.MINUTE_IN_MILLIS);
}
@@ -150,4 +168,14 @@ public class AnomalyDetectionPolicy {
return false; // Disabled when no this type
}
}
private Set<String> parseStringSet(final String key, final Set<String> defaultSet) {
final String value = mParserWrapper.getString(key, null);
if (value != null) {
return Arrays.stream(value.split(":"))
.map(String::trim).map(Uri::decode).collect(Collectors.toSet());
} else {
return defaultSet;
}
}
}

View File

@@ -21,6 +21,8 @@ import android.os.BatteryStats;
import android.support.annotation.VisibleForTesting;
import android.text.format.DateUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Log;
import com.android.internal.os.BatterySipper;
import com.android.internal.os.BatteryStatsHelper;
@@ -29,10 +31,12 @@ 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.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Check whether apps has too many wakeup alarms
@@ -42,6 +46,7 @@ public class WakeupAlarmAnomalyDetector implements AnomalyDetector {
@VisibleForTesting
BatteryUtils mBatteryUtils;
private long mWakeupAlarmThreshold;
private Set<String> mWakeupBlacklistedTags;
private Context mContext;
private AnomalyUtils mAnomalyUtils;
@@ -56,6 +61,7 @@ public class WakeupAlarmAnomalyDetector implements AnomalyDetector {
mBatteryUtils = BatteryUtils.getInstance(context);
mAnomalyUtils = anomalyUtils;
mWakeupAlarmThreshold = policy.wakeupAlarmThreshold;
mWakeupBlacklistedTags = policy.wakeupBlacklistedTags;
}
@Override
@@ -123,11 +129,14 @@ public class WakeupAlarmAnomalyDetector implements AnomalyDetector {
final BatteryStats.Uid.Pkg ps = packageStats.valueAt(ipkg);
final ArrayMap<String, ? extends BatteryStats.Counter> alarms =
ps.getWakeupAlarmStats();
for (int iwa = alarms.size() - 1; iwa >= 0; iwa--) {
int count = alarms.valueAt(iwa).getCountLocked(BatteryStats.STATS_SINCE_CHARGED);
for (Map.Entry<String, ? extends BatteryStats.Counter> alarm : alarms.entrySet()) {
if (mWakeupBlacklistedTags != null
&& mWakeupBlacklistedTags.contains(alarm.getKey())) {
continue;
}
int count = alarm.getValue().getCountLocked(BatteryStats.STATS_SINCE_CHARGED);
wakeups += count;
}
}
return wakeups;

View File

@@ -56,12 +56,22 @@ public class KeyValueListParserWrapper {
* Get the value for key as a boolean.
* @param key The key to lookup.
* @param defaultValue The value to return if the key was not found.
* @return the string value associated with the key.
* @return the boolean value associated with the key.
*/
public boolean getBoolean(String key, boolean defaultValue) {
return mParser.getBoolean(key, defaultValue);
}
/**
* Get the value for key as a string.
* @param key The key to lookup.
* @param defaultValue The value to return if the key was not found.
* @return the string value associated with the key.
*/
public String getString(String key, String defaultValue) {
return mParser.getString(key, defaultValue);
}
/**
* Get the value for key as a long.
* @param key The key to lookup.