Get anomalyType and autoRestriction from config
Now the westworld config provides COOKIES to store private info for each alert(anomaly). So we could use it to store: 1. AnomalyType: what is the type of anomaly 2. AutoRestriction: whether to auto restrict this anomaly Bug: 74567790 Test: RunSettingsRoboTests Change-Id: I15f5e225a4cb1f2da3fe109e56e5222816d179cc
This commit is contained in:
@@ -40,8 +40,11 @@ import android.support.annotation.VisibleForTesting;
|
|||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import com.android.internal.os.BatteryStatsHelper;
|
import com.android.internal.os.BatteryStatsHelper;
|
||||||
|
import com.android.internal.util.ArrayUtils;
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.fuelgauge.BatteryUtils;
|
import com.android.settings.fuelgauge.BatteryUtils;
|
||||||
|
import com.android.settings.fuelgauge.PowerUsageFeatureProvider;
|
||||||
|
import com.android.settings.overlay.FeatureFactory;
|
||||||
import com.android.settingslib.fuelgauge.PowerWhitelistBackend;
|
import com.android.settingslib.fuelgauge.PowerWhitelistBackend;
|
||||||
import com.android.settingslib.utils.ThreadUtils;
|
import com.android.settingslib.utils.ThreadUtils;
|
||||||
|
|
||||||
@@ -84,11 +87,14 @@ public class AnomalyDetectionJobService extends JobService {
|
|||||||
true /* collectBatteryBroadcast */);
|
true /* collectBatteryBroadcast */);
|
||||||
final UserManager userManager = getSystemService(UserManager.class);
|
final UserManager userManager = getSystemService(UserManager.class);
|
||||||
final PowerWhitelistBackend powerWhitelistBackend = PowerWhitelistBackend.getInstance();
|
final PowerWhitelistBackend powerWhitelistBackend = PowerWhitelistBackend.getInstance();
|
||||||
|
final PowerUsageFeatureProvider powerUsageFeatureProvider = FeatureFactory
|
||||||
|
.getFactory(this).getPowerUsageFeatureProvider(this);
|
||||||
|
|
||||||
for (JobWorkItem item = params.dequeueWork(); item != null;
|
for (JobWorkItem item = params.dequeueWork(); item != null;
|
||||||
item = params.dequeueWork()) {
|
item = params.dequeueWork()) {
|
||||||
saveAnomalyToDatabase(batteryStatsHelper, userManager, batteryDatabaseManager,
|
saveAnomalyToDatabase(batteryStatsHelper, userManager, batteryDatabaseManager,
|
||||||
batteryUtils, policy, powerWhitelistBackend, contentResolver,
|
batteryUtils, policy, powerWhitelistBackend, contentResolver,
|
||||||
|
powerUsageFeatureProvider,
|
||||||
item.getIntent().getExtras());
|
item.getIntent().getExtras());
|
||||||
}
|
}
|
||||||
jobFinished(params, false /* wantsReschedule */);
|
jobFinished(params, false /* wantsReschedule */);
|
||||||
@@ -106,42 +112,52 @@ public class AnomalyDetectionJobService extends JobService {
|
|||||||
void saveAnomalyToDatabase(BatteryStatsHelper batteryStatsHelper, UserManager userManager,
|
void saveAnomalyToDatabase(BatteryStatsHelper batteryStatsHelper, UserManager userManager,
|
||||||
BatteryDatabaseManager databaseManager, BatteryUtils batteryUtils,
|
BatteryDatabaseManager databaseManager, BatteryUtils batteryUtils,
|
||||||
BatteryTipPolicy policy, PowerWhitelistBackend powerWhitelistBackend,
|
BatteryTipPolicy policy, PowerWhitelistBackend powerWhitelistBackend,
|
||||||
ContentResolver contentResolver, Bundle bundle) {
|
ContentResolver contentResolver, PowerUsageFeatureProvider powerUsageFeatureProvider,
|
||||||
|
Bundle bundle) {
|
||||||
// The Example of intentDimsValue is: 35:{1:{1:{1:10013|}|}|}
|
// The Example of intentDimsValue is: 35:{1:{1:{1:10013|}|}|}
|
||||||
final StatsDimensionsValue intentDimsValue =
|
final StatsDimensionsValue intentDimsValue =
|
||||||
bundle.getParcelable(StatsManager.EXTRA_STATS_DIMENSIONS_VALUE);
|
bundle.getParcelable(StatsManager.EXTRA_STATS_DIMENSIONS_VALUE);
|
||||||
final long subscriptionId = bundle.getLong(StatsManager.EXTRA_STATS_SUBSCRIPTION_ID,
|
|
||||||
-1);
|
|
||||||
final long timeMs = bundle.getLong(AnomalyDetectionReceiver.KEY_ANOMALY_TIMESTAMP,
|
final long timeMs = bundle.getLong(AnomalyDetectionReceiver.KEY_ANOMALY_TIMESTAMP,
|
||||||
System.currentTimeMillis());
|
System.currentTimeMillis());
|
||||||
|
final String[] cookies = bundle.getStringArray(
|
||||||
|
StatsManager.EXTRA_STATS_BROADCAST_SUBSCRIBER_COOKIES);
|
||||||
|
final AnomalyInfo anomalyInfo = new AnomalyInfo(
|
||||||
|
!ArrayUtils.isEmpty(cookies) ? cookies[0] : "");
|
||||||
Log.i(TAG, "Extra stats value: " + intentDimsValue.toString());
|
Log.i(TAG, "Extra stats value: " + intentDimsValue.toString());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final int uid = extractUidFromStatsDimensionsValue(intentDimsValue);
|
final int uid = extractUidFromStatsDimensionsValue(intentDimsValue);
|
||||||
final int anomalyType = StatsManagerConfig.getAnomalyTypeFromSubscriptionId(
|
final boolean autoFeatureOn = powerUsageFeatureProvider.isSmartBatterySupported()
|
||||||
subscriptionId);
|
? Settings.Global.getInt(contentResolver,
|
||||||
final boolean smartBatteryOn = Settings.Global.getInt(contentResolver,
|
Settings.Global.APP_STANDBY_ENABLED, ON) == ON
|
||||||
Settings.Global.APP_STANDBY_ENABLED, ON) == ON;
|
: Settings.Global.getInt(contentResolver,
|
||||||
|
Settings.Global.APP_AUTO_RESTRICTION_ENABLED, ON) == ON;
|
||||||
final String packageName = batteryUtils.getPackageName(uid);
|
final String packageName = batteryUtils.getPackageName(uid);
|
||||||
if (!powerWhitelistBackend.isSysWhitelistedExceptIdle(packageName)
|
if (!powerWhitelistBackend.isSysWhitelistedExceptIdle(packageName)
|
||||||
&& !isSystemUid(uid)) {
|
&& !isSystemUid(uid)) {
|
||||||
if (anomalyType == StatsManagerConfig.AnomalyType.EXCESSIVE_BG) {
|
boolean anomalyDetected = true;
|
||||||
// TODO(b/72385333): check battery percentage draining in batterystats
|
if (anomalyInfo.anomalyType == StatsManagerConfig.AnomalyType.EXCESSIVE_BG) {
|
||||||
if (batteryUtils.isPreOApp(packageName) && batteryUtils.isAppHeavilyUsed(
|
if (!batteryUtils.isPreOApp(packageName)
|
||||||
batteryStatsHelper, userManager, uid,
|
|| !batteryUtils.isAppHeavilyUsed(batteryStatsHelper, userManager, uid,
|
||||||
policy.excessiveBgDrainPercentage)) {
|
policy.excessiveBgDrainPercentage)) {
|
||||||
Log.e(TAG, "Excessive detected uid=" + uid);
|
// Don't report if it is not legacy app or haven't used much battery
|
||||||
|
anomalyDetected = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (anomalyDetected) {
|
||||||
|
if (autoFeatureOn && anomalyInfo.autoRestriction) {
|
||||||
|
// Auto restrict this app
|
||||||
batteryUtils.setForceAppStandby(uid, packageName,
|
batteryUtils.setForceAppStandby(uid, packageName,
|
||||||
AppOpsManager.MODE_IGNORED);
|
AppOpsManager.MODE_IGNORED);
|
||||||
databaseManager.insertAnomaly(uid, packageName, anomalyType,
|
databaseManager.insertAnomaly(uid, packageName, anomalyInfo.anomalyType,
|
||||||
smartBatteryOn
|
AnomalyDatabaseHelper.State.AUTO_HANDLED,
|
||||||
? AnomalyDatabaseHelper.State.AUTO_HANDLED
|
timeMs);
|
||||||
: AnomalyDatabaseHelper.State.NEW,
|
} else {
|
||||||
|
databaseManager.insertAnomaly(uid, packageName, anomalyInfo.anomalyType,
|
||||||
|
AnomalyDatabaseHelper.State.NEW,
|
||||||
timeMs);
|
timeMs);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
databaseManager.insertAnomaly(uid, packageName, anomalyType,
|
|
||||||
AnomalyDatabaseHelper.State.NEW, timeMs);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (NullPointerException | IndexOutOfBoundsException e) {
|
} catch (NullPointerException | IndexOutOfBoundsException e) {
|
||||||
|
@@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 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.batterytip;
|
||||||
|
|
||||||
|
import android.util.KeyValueListParser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Model class to parse and store anomaly info from westworld
|
||||||
|
*/
|
||||||
|
public class AnomalyInfo {
|
||||||
|
private static final String KEY_ANOMALY_TYPE = "anomaly_type";
|
||||||
|
private static final String KEY_AUTO_RESTRICTION = "auto_restriction";
|
||||||
|
public final Integer anomalyType;
|
||||||
|
public final boolean autoRestriction;
|
||||||
|
|
||||||
|
public AnomalyInfo(String info) {
|
||||||
|
KeyValueListParser parser = new KeyValueListParser(',');
|
||||||
|
parser.setString(info);
|
||||||
|
anomalyType = parser.getInt(KEY_ANOMALY_TYPE, -1);
|
||||||
|
autoRestriction = parser.getBoolean(KEY_AUTO_RESTRICTION, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -41,22 +41,6 @@ public class StatsManagerConfig {
|
|||||||
*/
|
*/
|
||||||
public static final long SUBSCRIBER_ID = 1;
|
public static final long SUBSCRIBER_ID = 1;
|
||||||
|
|
||||||
private static final Map<Long, Integer> ANOMALY_TYPE;
|
|
||||||
|
|
||||||
private static final HashFunction HASH_FUNCTION = Hashing.sha256();
|
|
||||||
|
|
||||||
static {
|
|
||||||
ANOMALY_TYPE = new HashMap<>();
|
|
||||||
ANOMALY_TYPE.put(hash("SUBSCRIPTION:SETTINGS_EXCESSIVE_BACKGROUND_SERVICE"),
|
|
||||||
AnomalyType.EXCESSIVE_BG);
|
|
||||||
ANOMALY_TYPE.put(hash("SUBSCRIPTION:SETTINGS_LONG_UNOPTIMIZED_BLE_SCAN"),
|
|
||||||
AnomalyType.BLUETOOTH_SCAN);
|
|
||||||
ANOMALY_TYPE.put(hash("SUBSCRIPTION:SETTINGS_EXCESSIVE_WAKEUPS_IN_BACKGROUND"),
|
|
||||||
AnomalyType.WAKEUP_ALARM);
|
|
||||||
ANOMALY_TYPE.put(hash("SUBSCRIPTION:SETTINGS_EXCESSIVE_WAKELOCK_ALL_SCREEN_OFF"),
|
|
||||||
AnomalyType.WAKE_LOCK);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Retention(RetentionPolicy.SOURCE)
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
@IntDef({AnomalyType.NULL,
|
@IntDef({AnomalyType.NULL,
|
||||||
AnomalyType.WAKE_LOCK,
|
AnomalyType.WAKE_LOCK,
|
||||||
@@ -71,11 +55,4 @@ public class StatsManagerConfig {
|
|||||||
int EXCESSIVE_BG = 3;
|
int EXCESSIVE_BG = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getAnomalyTypeFromSubscriptionId(long subscriptionId) {
|
|
||||||
return ANOMALY_TYPE.getOrDefault(subscriptionId, AnomalyType.NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static long hash(CharSequence value) {
|
|
||||||
return HASH_FUNCTION.hashUnencodedChars(value).asLong();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -22,6 +22,7 @@ import static org.mockito.Matchers.any;
|
|||||||
import static org.mockito.Matchers.anyInt;
|
import static org.mockito.Matchers.anyInt;
|
||||||
import static org.mockito.Matchers.anyLong;
|
import static org.mockito.Matchers.anyLong;
|
||||||
import static org.mockito.Matchers.anyString;
|
import static org.mockito.Matchers.anyString;
|
||||||
|
import static org.mockito.Matchers.eq;
|
||||||
import static org.mockito.Mockito.doReturn;
|
import static org.mockito.Mockito.doReturn;
|
||||||
import static org.mockito.Mockito.never;
|
import static org.mockito.Mockito.never;
|
||||||
import static org.mockito.Mockito.spy;
|
import static org.mockito.Mockito.spy;
|
||||||
@@ -41,6 +42,8 @@ import android.os.UserManager;
|
|||||||
import com.android.internal.os.BatteryStatsHelper;
|
import com.android.internal.os.BatteryStatsHelper;
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.fuelgauge.BatteryUtils;
|
import com.android.settings.fuelgauge.BatteryUtils;
|
||||||
|
import com.android.settings.overlay.FeatureFactory;
|
||||||
|
import com.android.settings.testutils.FakeFeatureFactory;
|
||||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||||
import com.android.settingslib.fuelgauge.PowerWhitelistBackend;
|
import com.android.settingslib.fuelgauge.PowerWhitelistBackend;
|
||||||
|
|
||||||
@@ -60,6 +63,10 @@ import java.util.concurrent.TimeUnit;
|
|||||||
public class AnomalyDetectionJobServiceTest {
|
public class AnomalyDetectionJobServiceTest {
|
||||||
private static final int UID = 123;
|
private static final int UID = 123;
|
||||||
private static final String SYSTEM_PACKAGE = "com.android.system";
|
private static final String SYSTEM_PACKAGE = "com.android.system";
|
||||||
|
private static final String SUBSCRIBER_COOKIES_AUTO_RESTRICTION =
|
||||||
|
"anomaly_type=6,auto_restriction=true";
|
||||||
|
private static final String SUBSCRIBER_COOKIES_NOT_AUTO_RESTRICTION =
|
||||||
|
"anomaly_type=6,auto_restriction=false";
|
||||||
@Mock
|
@Mock
|
||||||
private BatteryStatsHelper mBatteryStatsHelper;
|
private BatteryStatsHelper mBatteryStatsHelper;
|
||||||
@Mock
|
@Mock
|
||||||
@@ -76,6 +83,7 @@ public class AnomalyDetectionJobServiceTest {
|
|||||||
private BatteryTipPolicy mPolicy;
|
private BatteryTipPolicy mPolicy;
|
||||||
private Bundle mBundle;
|
private Bundle mBundle;
|
||||||
private AnomalyDetectionJobService mAnomalyDetectionJobService;
|
private AnomalyDetectionJobService mAnomalyDetectionJobService;
|
||||||
|
private FakeFeatureFactory mFeatureFactory;
|
||||||
private Context mContext;
|
private Context mContext;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
@@ -86,6 +94,7 @@ public class AnomalyDetectionJobServiceTest {
|
|||||||
mPolicy = new BatteryTipPolicy(mContext);
|
mPolicy = new BatteryTipPolicy(mContext);
|
||||||
mBundle = new Bundle();
|
mBundle = new Bundle();
|
||||||
mBundle.putParcelable(StatsManager.EXTRA_STATS_DIMENSIONS_VALUE, mStatsDimensionsValue);
|
mBundle.putParcelable(StatsManager.EXTRA_STATS_DIMENSIONS_VALUE, mStatsDimensionsValue);
|
||||||
|
mFeatureFactory = FakeFeatureFactory.setupForTest();
|
||||||
|
|
||||||
mAnomalyDetectionJobService = spy(new AnomalyDetectionJobService());
|
mAnomalyDetectionJobService = spy(new AnomalyDetectionJobService());
|
||||||
}
|
}
|
||||||
@@ -112,7 +121,7 @@ public class AnomalyDetectionJobServiceTest {
|
|||||||
|
|
||||||
mAnomalyDetectionJobService.saveAnomalyToDatabase(mBatteryStatsHelper, mUserManager,
|
mAnomalyDetectionJobService.saveAnomalyToDatabase(mBatteryStatsHelper, mUserManager,
|
||||||
mBatteryDatabaseManager, mBatteryUtils, mPolicy, mPowerWhitelistBackend,
|
mBatteryDatabaseManager, mBatteryUtils, mPolicy, mPowerWhitelistBackend,
|
||||||
mContext.getContentResolver(), mBundle);
|
mContext.getContentResolver(), mFeatureFactory.powerUsageFeatureProvider, mBundle);
|
||||||
|
|
||||||
verify(mBatteryDatabaseManager, never()).insertAnomaly(anyInt(), anyString(), anyInt(),
|
verify(mBatteryDatabaseManager, never()).insertAnomaly(anyInt(), anyString(), anyInt(),
|
||||||
anyInt(), anyLong());
|
anyInt(), anyLong());
|
||||||
@@ -125,14 +134,16 @@ public class AnomalyDetectionJobServiceTest {
|
|||||||
|
|
||||||
mAnomalyDetectionJobService.saveAnomalyToDatabase(mBatteryStatsHelper, mUserManager,
|
mAnomalyDetectionJobService.saveAnomalyToDatabase(mBatteryStatsHelper, mUserManager,
|
||||||
mBatteryDatabaseManager, mBatteryUtils, mPolicy, mPowerWhitelistBackend,
|
mBatteryDatabaseManager, mBatteryUtils, mPolicy, mPowerWhitelistBackend,
|
||||||
mContext.getContentResolver(), mBundle);
|
mContext.getContentResolver(), mFeatureFactory.powerUsageFeatureProvider, mBundle);
|
||||||
|
|
||||||
verify(mBatteryDatabaseManager, never()).insertAnomaly(anyInt(), anyString(), anyInt(),
|
verify(mBatteryDatabaseManager, never()).insertAnomaly(anyInt(), anyString(), anyInt(),
|
||||||
anyInt(), anyLong());
|
anyInt(), anyLong());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSaveAnomalyToDatabase_normalApp_save() {
|
public void testSaveAnomalyToDatabase_normalAppWithAutoRestriction_save() {
|
||||||
|
mBundle.putStringArray(StatsManager.EXTRA_STATS_BROADCAST_SUBSCRIBER_COOKIES,
|
||||||
|
new String[]{SUBSCRIBER_COOKIES_AUTO_RESTRICTION});
|
||||||
doReturn(SYSTEM_PACKAGE).when(mBatteryUtils).getPackageName(anyInt());
|
doReturn(SYSTEM_PACKAGE).when(mBatteryUtils).getPackageName(anyInt());
|
||||||
doReturn(false).when(mPowerWhitelistBackend).isSysWhitelisted(SYSTEM_PACKAGE);
|
doReturn(false).when(mPowerWhitelistBackend).isSysWhitelisted(SYSTEM_PACKAGE);
|
||||||
doReturn(Process.FIRST_APPLICATION_UID).when(
|
doReturn(Process.FIRST_APPLICATION_UID).when(
|
||||||
@@ -140,9 +151,27 @@ public class AnomalyDetectionJobServiceTest {
|
|||||||
|
|
||||||
mAnomalyDetectionJobService.saveAnomalyToDatabase(mBatteryStatsHelper, mUserManager,
|
mAnomalyDetectionJobService.saveAnomalyToDatabase(mBatteryStatsHelper, mUserManager,
|
||||||
mBatteryDatabaseManager, mBatteryUtils, mPolicy, mPowerWhitelistBackend,
|
mBatteryDatabaseManager, mBatteryUtils, mPolicy, mPowerWhitelistBackend,
|
||||||
mContext.getContentResolver(), mBundle);
|
mContext.getContentResolver(), mFeatureFactory.powerUsageFeatureProvider, mBundle);
|
||||||
|
|
||||||
verify(mBatteryDatabaseManager).insertAnomaly(anyInt(), anyString(), anyInt(), anyInt(),
|
verify(mBatteryDatabaseManager).insertAnomaly(anyInt(), anyString(), eq(6),
|
||||||
anyLong());
|
eq(AnomalyDatabaseHelper.State.AUTO_HANDLED), anyLong());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSaveAnomalyToDatabase_normalAppWithoutAutoRestriction_save() {
|
||||||
|
mBundle.putStringArray(StatsManager.EXTRA_STATS_BROADCAST_SUBSCRIBER_COOKIES,
|
||||||
|
new String[]{SUBSCRIBER_COOKIES_NOT_AUTO_RESTRICTION});
|
||||||
|
doReturn(SYSTEM_PACKAGE).when(mBatteryUtils).getPackageName(anyInt());
|
||||||
|
doReturn(false).when(mPowerWhitelistBackend).isSysWhitelisted(SYSTEM_PACKAGE);
|
||||||
|
doReturn(Process.FIRST_APPLICATION_UID).when(
|
||||||
|
mAnomalyDetectionJobService).extractUidFromStatsDimensionsValue(any());
|
||||||
|
|
||||||
|
mAnomalyDetectionJobService.saveAnomalyToDatabase(mBatteryStatsHelper, mUserManager,
|
||||||
|
mBatteryDatabaseManager, mBatteryUtils, mPolicy, mPowerWhitelistBackend,
|
||||||
|
mContext.getContentResolver(), mFeatureFactory.powerUsageFeatureProvider, mBundle);
|
||||||
|
|
||||||
|
verify(mBatteryDatabaseManager).insertAnomaly(anyInt(), anyString(), eq(6),
|
||||||
|
eq(AnomalyDatabaseHelper.State.NEW), anyLong());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user