Merge "Add whitelist for anomaly detection." into pi-dev
am: 13eb2f18b4
Change-Id: I2fd14ec8f8f1770856c8aabf49e0e39210a08293
This commit is contained in:
@@ -41,6 +41,7 @@ import android.util.Log;
|
||||
import com.android.internal.os.BatteryStatsHelper;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.fuelgauge.BatteryUtils;
|
||||
import com.android.settingslib.fuelgauge.PowerWhitelistBackend;
|
||||
import com.android.settingslib.utils.ThreadUtils;
|
||||
|
||||
import java.util.List;
|
||||
@@ -81,11 +82,12 @@ public class AnomalyDetectionJobService extends JobService {
|
||||
final BatteryStatsHelper batteryStatsHelper = new BatteryStatsHelper(this,
|
||||
true /* collectBatteryBroadcast */);
|
||||
final UserManager userManager = getSystemService(UserManager.class);
|
||||
final PowerWhitelistBackend powerWhitelistBackend = PowerWhitelistBackend.getInstance();
|
||||
|
||||
for (JobWorkItem item = params.dequeueWork(); item != null;
|
||||
item = params.dequeueWork()) {
|
||||
saveAnomalyToDatabase(batteryStatsHelper, userManager, batteryDatabaseManager,
|
||||
batteryUtils, policy, contentResolver,
|
||||
batteryUtils, policy, powerWhitelistBackend, contentResolver,
|
||||
item.getIntent().getExtras());
|
||||
}
|
||||
jobFinished(params, false /* wantsReschedule */);
|
||||
@@ -102,7 +104,8 @@ public class AnomalyDetectionJobService extends JobService {
|
||||
@VisibleForTesting
|
||||
void saveAnomalyToDatabase(BatteryStatsHelper batteryStatsHelper, UserManager userManager,
|
||||
BatteryDatabaseManager databaseManager, BatteryUtils batteryUtils,
|
||||
BatteryTipPolicy policy, ContentResolver contentResolver, Bundle bundle) {
|
||||
BatteryTipPolicy policy, PowerWhitelistBackend powerWhitelistBackend,
|
||||
ContentResolver contentResolver, Bundle bundle) {
|
||||
// The Example of intentDimsValue is: 35:{1:{1:{1:10013|}|}|}
|
||||
final StatsDimensionsValue intentDimsValue =
|
||||
bundle.getParcelable(StatsManager.EXTRA_STATS_DIMENSIONS_VALUE);
|
||||
@@ -119,24 +122,25 @@ public class AnomalyDetectionJobService extends JobService {
|
||||
final boolean smartBatteryOn = Settings.Global.getInt(contentResolver,
|
||||
Settings.Global.APP_STANDBY_ENABLED, ON) == ON;
|
||||
final String packageName = batteryUtils.getPackageName(uid);
|
||||
|
||||
if (anomalyType == StatsManagerConfig.AnomalyType.EXCESSIVE_BG) {
|
||||
// TODO(b/72385333): check battery percentage draining in batterystats
|
||||
if (batteryUtils.isLegacyApp(packageName) && batteryUtils.isAppHeavilyUsed(
|
||||
batteryStatsHelper, userManager, uid,
|
||||
policy.excessiveBgDrainPercentage)) {
|
||||
Log.e(TAG, "Excessive detected uid=" + uid);
|
||||
batteryUtils.setForceAppStandby(uid, packageName,
|
||||
AppOpsManager.MODE_IGNORED);
|
||||
if (!powerWhitelistBackend.isSysWhitelisted(packageName)) {
|
||||
if (anomalyType == StatsManagerConfig.AnomalyType.EXCESSIVE_BG) {
|
||||
// TODO(b/72385333): check battery percentage draining in batterystats
|
||||
if (batteryUtils.isLegacyApp(packageName) && batteryUtils.isAppHeavilyUsed(
|
||||
batteryStatsHelper, userManager, uid,
|
||||
policy.excessiveBgDrainPercentage)) {
|
||||
Log.e(TAG, "Excessive detected uid=" + uid);
|
||||
batteryUtils.setForceAppStandby(uid, packageName,
|
||||
AppOpsManager.MODE_IGNORED);
|
||||
databaseManager.insertAnomaly(uid, packageName, anomalyType,
|
||||
smartBatteryOn
|
||||
? AnomalyDatabaseHelper.State.AUTO_HANDLED
|
||||
: AnomalyDatabaseHelper.State.NEW,
|
||||
timeMs);
|
||||
}
|
||||
} else {
|
||||
databaseManager.insertAnomaly(uid, packageName, anomalyType,
|
||||
smartBatteryOn
|
||||
? AnomalyDatabaseHelper.State.AUTO_HANDLED
|
||||
: AnomalyDatabaseHelper.State.NEW,
|
||||
timeMs);
|
||||
AnomalyDatabaseHelper.State.NEW, timeMs);
|
||||
}
|
||||
} else {
|
||||
databaseManager.insertAnomaly(uid, packageName, anomalyType,
|
||||
AnomalyDatabaseHelper.State.NEW, timeMs);
|
||||
}
|
||||
} catch (NullPointerException | IndexOutOfBoundsException e) {
|
||||
Log.e(TAG, "Parse stats dimensions value error.", e);
|
||||
|
@@ -18,10 +18,10 @@ package com.android.settings.fuelgauge.batterytip;
|
||||
|
||||
import static com.android.settings.fuelgauge.batterytip.AnomalyDatabaseHelper.AnomalyColumns
|
||||
.ANOMALY_STATE;
|
||||
import static com.android.settings.fuelgauge.batterytip.AnomalyDatabaseHelper.AnomalyColumns
|
||||
.PACKAGE_NAME;
|
||||
import static com.android.settings.fuelgauge.batterytip.AnomalyDatabaseHelper.AnomalyColumns
|
||||
.ANOMALY_TYPE;
|
||||
import static com.android.settings.fuelgauge.batterytip.AnomalyDatabaseHelper.AnomalyColumns
|
||||
.PACKAGE_NAME;
|
||||
import static com.android.settings.fuelgauge.batterytip.AnomalyDatabaseHelper.AnomalyColumns
|
||||
.TIME_STAMP_MS;
|
||||
import static com.android.settings.fuelgauge.batterytip.AnomalyDatabaseHelper.AnomalyColumns.UID;
|
||||
@@ -61,10 +61,11 @@ public class BatteryDatabaseManager {
|
||||
|
||||
/**
|
||||
* Insert an anomaly log to database.
|
||||
* @param packageName the package name of the app
|
||||
* @param type the type of the anomaly
|
||||
* @param anomalyState the state of the anomaly
|
||||
* @param timestampMs the time when it is happened
|
||||
*
|
||||
* @param packageName the package name of the app
|
||||
* @param type the type of the anomaly
|
||||
* @param anomalyState the state of the anomaly
|
||||
* @param timestampMs the time when it is happened
|
||||
*/
|
||||
public synchronized void insertAnomaly(int uid, String packageName, int type, int anomalyState,
|
||||
long timestampMs) {
|
||||
|
@@ -17,17 +17,36 @@
|
||||
package com.android.settings.fuelgauge.batterytip;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Matchers.anyInt;
|
||||
import static org.mockito.Matchers.anyLong;
|
||||
import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.robolectric.RuntimeEnvironment.application;
|
||||
|
||||
import android.app.StatsManager;
|
||||
import android.app.job.JobInfo;
|
||||
import android.app.job.JobScheduler;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.StatsDimensionsValue;
|
||||
import android.os.UserManager;
|
||||
|
||||
import com.android.internal.os.BatteryStatsHelper;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.fuelgauge.BatteryUtils;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
import com.android.settingslib.fuelgauge.PowerWhitelistBackend;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.Shadows;
|
||||
import org.robolectric.shadows.ShadowJobScheduler;
|
||||
|
||||
@@ -36,6 +55,37 @@ import java.util.concurrent.TimeUnit;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
public class AnomalyDetectionJobServiceTest {
|
||||
private static final int UID = 123;
|
||||
private static final String SYSTEM_PACKAGE = "com.android.system";
|
||||
@Mock
|
||||
private BatteryStatsHelper mBatteryStatsHelper;
|
||||
@Mock
|
||||
private UserManager mUserManager;
|
||||
@Mock
|
||||
private BatteryDatabaseManager mBatteryDatabaseManager;
|
||||
@Mock
|
||||
private BatteryUtils mBatteryUtils;
|
||||
@Mock
|
||||
private PowerWhitelistBackend mPowerWhitelistBackend;
|
||||
@Mock
|
||||
private StatsDimensionsValue mStatsDimensionsValue;
|
||||
|
||||
private BatteryTipPolicy mPolicy;
|
||||
private Bundle mBundle;
|
||||
private AnomalyDetectionJobService mAnomalyDetectionJobService;
|
||||
private Context mContext;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
mContext = RuntimeEnvironment.application;
|
||||
mPolicy = new BatteryTipPolicy(mContext);
|
||||
mBundle = new Bundle();
|
||||
mBundle.putParcelable(StatsManager.EXTRA_STATS_DIMENSIONS_VALUE, mStatsDimensionsValue);
|
||||
|
||||
mAnomalyDetectionJobService = new AnomalyDetectionJobService();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testScheduleCleanUp() {
|
||||
@@ -50,4 +100,30 @@ public class AnomalyDetectionJobServiceTest {
|
||||
assertThat(pendingJob.getMaxExecutionDelayMillis())
|
||||
.isEqualTo(TimeUnit.MINUTES.toMillis(30));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSaveAnomalyToDatabase_systemWhitelisted_doNotSave() {
|
||||
doReturn(SYSTEM_PACKAGE).when(mBatteryUtils).getPackageName(anyInt());
|
||||
doReturn(true).when(mPowerWhitelistBackend).isSysWhitelisted(SYSTEM_PACKAGE);
|
||||
|
||||
mAnomalyDetectionJobService.saveAnomalyToDatabase(mBatteryStatsHelper, mUserManager,
|
||||
mBatteryDatabaseManager, mBatteryUtils, mPolicy, mPowerWhitelistBackend,
|
||||
mContext.getContentResolver(), mBundle);
|
||||
|
||||
verify(mBatteryDatabaseManager, never()).insertAnomaly(anyInt(), anyString(), anyInt(),
|
||||
anyInt(), anyLong());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSaveAnomalyToDatabase_normalApp_save() {
|
||||
doReturn(SYSTEM_PACKAGE).when(mBatteryUtils).getPackageName(anyInt());
|
||||
doReturn(false).when(mPowerWhitelistBackend).isSysWhitelisted(SYSTEM_PACKAGE);
|
||||
|
||||
mAnomalyDetectionJobService.saveAnomalyToDatabase(mBatteryStatsHelper, mUserManager,
|
||||
mBatteryDatabaseManager, mBatteryUtils, mPolicy, mPowerWhitelistBackend,
|
||||
mContext.getContentResolver(), mBundle);
|
||||
|
||||
verify(mBatteryDatabaseManager).insertAnomaly(anyInt(), anyString(), anyInt(), anyInt(),
|
||||
anyLong());
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user