Add whitelist for anomaly detection.
Even though we can add whitelist in config, we still need to have a on device whitelist to reduce the size of config. Use doze whitelist here because we already used it to detect whether we can restrict the app in battery detail page. Bug: 74241534 Test: RunSettingsRoboTests Change-Id: I35b6f3eba9fbc8ae51bb02cd9d5416e4360c388e
This commit is contained in:
@@ -41,6 +41,7 @@ import android.util.Log;
|
|||||||
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.settingslib.fuelgauge.PowerWhitelistBackend;
|
||||||
import com.android.settingslib.utils.ThreadUtils;
|
import com.android.settingslib.utils.ThreadUtils;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -81,11 +82,12 @@ public class AnomalyDetectionJobService extends JobService {
|
|||||||
final BatteryStatsHelper batteryStatsHelper = new BatteryStatsHelper(this,
|
final BatteryStatsHelper batteryStatsHelper = new BatteryStatsHelper(this,
|
||||||
true /* collectBatteryBroadcast */);
|
true /* collectBatteryBroadcast */);
|
||||||
final UserManager userManager = getSystemService(UserManager.class);
|
final UserManager userManager = getSystemService(UserManager.class);
|
||||||
|
final PowerWhitelistBackend powerWhitelistBackend = PowerWhitelistBackend.getInstance();
|
||||||
|
|
||||||
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, contentResolver,
|
batteryUtils, policy, powerWhitelistBackend, contentResolver,
|
||||||
item.getIntent().getExtras());
|
item.getIntent().getExtras());
|
||||||
}
|
}
|
||||||
jobFinished(params, false /* wantsReschedule */);
|
jobFinished(params, false /* wantsReschedule */);
|
||||||
@@ -102,7 +104,8 @@ public class AnomalyDetectionJobService extends JobService {
|
|||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
void saveAnomalyToDatabase(BatteryStatsHelper batteryStatsHelper, UserManager userManager,
|
void saveAnomalyToDatabase(BatteryStatsHelper batteryStatsHelper, UserManager userManager,
|
||||||
BatteryDatabaseManager databaseManager, BatteryUtils batteryUtils,
|
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|}|}|}
|
// 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);
|
||||||
@@ -119,7 +122,7 @@ public class AnomalyDetectionJobService extends JobService {
|
|||||||
final boolean smartBatteryOn = 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;
|
||||||
final String packageName = batteryUtils.getPackageName(uid);
|
final String packageName = batteryUtils.getPackageName(uid);
|
||||||
|
if (!powerWhitelistBackend.isSysWhitelisted(packageName)) {
|
||||||
if (anomalyType == StatsManagerConfig.AnomalyType.EXCESSIVE_BG) {
|
if (anomalyType == StatsManagerConfig.AnomalyType.EXCESSIVE_BG) {
|
||||||
// TODO(b/72385333): check battery percentage draining in batterystats
|
// TODO(b/72385333): check battery percentage draining in batterystats
|
||||||
if (batteryUtils.isLegacyApp(packageName) && batteryUtils.isAppHeavilyUsed(
|
if (batteryUtils.isLegacyApp(packageName) && batteryUtils.isAppHeavilyUsed(
|
||||||
@@ -138,6 +141,7 @@ public class AnomalyDetectionJobService extends JobService {
|
|||||||
databaseManager.insertAnomaly(uid, packageName, anomalyType,
|
databaseManager.insertAnomaly(uid, packageName, anomalyType,
|
||||||
AnomalyDatabaseHelper.State.NEW, timeMs);
|
AnomalyDatabaseHelper.State.NEW, timeMs);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} catch (NullPointerException | IndexOutOfBoundsException e) {
|
} catch (NullPointerException | IndexOutOfBoundsException e) {
|
||||||
Log.e(TAG, "Parse stats dimensions value error.", 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
|
import static com.android.settings.fuelgauge.batterytip.AnomalyDatabaseHelper.AnomalyColumns
|
||||||
.ANOMALY_STATE;
|
.ANOMALY_STATE;
|
||||||
import static com.android.settings.fuelgauge.batterytip.AnomalyDatabaseHelper.AnomalyColumns
|
|
||||||
.PACKAGE_NAME;
|
|
||||||
import static com.android.settings.fuelgauge.batterytip.AnomalyDatabaseHelper.AnomalyColumns
|
import static com.android.settings.fuelgauge.batterytip.AnomalyDatabaseHelper.AnomalyColumns
|
||||||
.ANOMALY_TYPE;
|
.ANOMALY_TYPE;
|
||||||
|
import static com.android.settings.fuelgauge.batterytip.AnomalyDatabaseHelper.AnomalyColumns
|
||||||
|
.PACKAGE_NAME;
|
||||||
import static com.android.settings.fuelgauge.batterytip.AnomalyDatabaseHelper.AnomalyColumns
|
import static com.android.settings.fuelgauge.batterytip.AnomalyDatabaseHelper.AnomalyColumns
|
||||||
.TIME_STAMP_MS;
|
.TIME_STAMP_MS;
|
||||||
import static com.android.settings.fuelgauge.batterytip.AnomalyDatabaseHelper.AnomalyColumns.UID;
|
import static com.android.settings.fuelgauge.batterytip.AnomalyDatabaseHelper.AnomalyColumns.UID;
|
||||||
@@ -61,6 +61,7 @@ public class BatteryDatabaseManager {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Insert an anomaly log to database.
|
* Insert an anomaly log to database.
|
||||||
|
*
|
||||||
* @param packageName the package name of the app
|
* @param packageName the package name of the app
|
||||||
* @param type the type of the anomaly
|
* @param type the type of the anomaly
|
||||||
* @param anomalyState the state of the anomaly
|
* @param anomalyState the state of the anomaly
|
||||||
|
@@ -17,17 +17,36 @@
|
|||||||
package com.android.settings.fuelgauge.batterytip;
|
package com.android.settings.fuelgauge.batterytip;
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
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 static org.robolectric.RuntimeEnvironment.application;
|
||||||
|
|
||||||
|
import android.app.StatsManager;
|
||||||
import android.app.job.JobInfo;
|
import android.app.job.JobInfo;
|
||||||
import android.app.job.JobScheduler;
|
import android.app.job.JobScheduler;
|
||||||
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
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.R;
|
||||||
|
import com.android.settings.fuelgauge.BatteryUtils;
|
||||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||||
|
import com.android.settingslib.fuelgauge.PowerWhitelistBackend;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
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;
|
||||||
import org.robolectric.shadows.ShadowJobScheduler;
|
import org.robolectric.shadows.ShadowJobScheduler;
|
||||||
|
|
||||||
@@ -36,6 +55,37 @@ import java.util.concurrent.TimeUnit;
|
|||||||
|
|
||||||
@RunWith(SettingsRobolectricTestRunner.class)
|
@RunWith(SettingsRobolectricTestRunner.class)
|
||||||
public class AnomalyDetectionJobServiceTest {
|
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
|
@Test
|
||||||
public void testScheduleCleanUp() {
|
public void testScheduleCleanUp() {
|
||||||
@@ -50,4 +100,30 @@ public class AnomalyDetectionJobServiceTest {
|
|||||||
assertThat(pendingJob.getMaxExecutionDelayMillis())
|
assertThat(pendingJob.getMaxExecutionDelayMillis())
|
||||||
.isEqualTo(TimeUnit.MINUTES.toMillis(30));
|
.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