Clean up the legacy anomaly detection mechanism in the Settings
Clean up the legacy anomaly detection mechanism in the Settings, which is implemented in the 2017-2018. The will be replaced by the new anomaly detection mechanism. Bug: n/a Test: make -j64 RunSettingsRoboTests ROBOTEST_FILTER="com.android.settings.fuelgauge" Change-Id: I12ee6c8b3cbdb5073e4d46f18b90f8de228be8a8
This commit is contained in:
@@ -22,17 +22,14 @@ import android.content.pm.ApplicationInfo;
|
|||||||
import android.content.pm.InstallSourceInfo;
|
import android.content.pm.InstallSourceInfo;
|
||||||
import android.content.pm.PackageInfo;
|
import android.content.pm.PackageInfo;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.pm.ResolveInfo;
|
|
||||||
import android.os.BatteryManager;
|
import android.os.BatteryManager;
|
||||||
import android.os.BatteryStats;
|
import android.os.BatteryStats;
|
||||||
import android.os.BatteryStatsManager;
|
import android.os.BatteryStatsManager;
|
||||||
import android.os.BatteryUsageStats;
|
import android.os.BatteryUsageStats;
|
||||||
import android.os.BatteryUsageStatsQuery;
|
import android.os.BatteryUsageStatsQuery;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Process;
|
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
import android.os.UidBatteryConsumer;
|
import android.os.UidBatteryConsumer;
|
||||||
import android.os.UserHandle;
|
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.text.format.DateUtils;
|
import android.text.format.DateUtils;
|
||||||
@@ -47,14 +44,11 @@ import androidx.annotation.WorkerThread;
|
|||||||
import com.android.internal.util.ArrayUtils;
|
import com.android.internal.util.ArrayUtils;
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.fuelgauge.batterytip.AnomalyDatabaseHelper;
|
import com.android.settings.fuelgauge.batterytip.AnomalyDatabaseHelper;
|
||||||
import com.android.settings.fuelgauge.batterytip.AnomalyInfo;
|
|
||||||
import com.android.settings.fuelgauge.batterytip.BatteryDatabaseManager;
|
import com.android.settings.fuelgauge.batterytip.BatteryDatabaseManager;
|
||||||
import com.android.settings.fuelgauge.batterytip.StatsManagerConfig;
|
|
||||||
import com.android.settings.overlay.FeatureFactory;
|
import com.android.settings.overlay.FeatureFactory;
|
||||||
import com.android.settingslib.applications.AppUtils;
|
import com.android.settingslib.applications.AppUtils;
|
||||||
import com.android.settingslib.fuelgauge.Estimate;
|
import com.android.settingslib.fuelgauge.Estimate;
|
||||||
import com.android.settingslib.fuelgauge.EstimateKt;
|
import com.android.settingslib.fuelgauge.EstimateKt;
|
||||||
import com.android.settingslib.fuelgauge.PowerAllowlistBackend;
|
|
||||||
import com.android.settingslib.utils.PowerUtil;
|
import com.android.settingslib.utils.PowerUtil;
|
||||||
import com.android.settingslib.utils.StringUtil;
|
import com.android.settingslib.utils.StringUtil;
|
||||||
import com.android.settingslib.utils.ThreadUtils;
|
import com.android.settingslib.utils.ThreadUtils;
|
||||||
@@ -68,7 +62,6 @@ import java.time.Instant;
|
|||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.time.format.FormatStyle;
|
import java.time.format.FormatStyle;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/** Utils for battery operation */
|
/** Utils for battery operation */
|
||||||
public class BatteryUtils {
|
public class BatteryUtils {
|
||||||
@@ -548,74 +541,6 @@ public class BatteryUtils {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return {@code true} if we should hide anomaly app represented by {@code uid} */
|
|
||||||
public boolean shouldHideAnomaly(
|
|
||||||
PowerAllowlistBackend powerAllowlistBackend, int uid, AnomalyInfo anomalyInfo) {
|
|
||||||
final String[] packageNames = mPackageManager.getPackagesForUid(uid);
|
|
||||||
if (ArrayUtils.isEmpty(packageNames)) {
|
|
||||||
// Don't show it if app has been uninstalled
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return isSystemUid(uid)
|
|
||||||
|| powerAllowlistBackend.isAllowlisted(packageNames, uid)
|
|
||||||
|| (isSystemApp(mPackageManager, packageNames) && !hasLauncherEntry(packageNames))
|
|
||||||
|| (isExcessiveBackgroundAnomaly(anomalyInfo) && !isPreOApp(packageNames));
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isExcessiveBackgroundAnomaly(AnomalyInfo anomalyInfo) {
|
|
||||||
return anomalyInfo.anomalyType
|
|
||||||
== StatsManagerConfig.AnomalyType.EXCESSIVE_BACKGROUND_SERVICE;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isSystemUid(int uid) {
|
|
||||||
final int appUid = UserHandle.getAppId(uid);
|
|
||||||
return appUid >= Process.ROOT_UID && appUid < Process.FIRST_APPLICATION_UID;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isSystemApp(PackageManager packageManager, String[] packageNames) {
|
|
||||||
for (String packageName : packageNames) {
|
|
||||||
try {
|
|
||||||
final ApplicationInfo info =
|
|
||||||
packageManager.getApplicationInfo(packageName, 0 /* flags */);
|
|
||||||
if ((info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} catch (PackageManager.NameNotFoundException e) {
|
|
||||||
Log.e(TAG, "Package not found: " + packageName, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean hasLauncherEntry(String[] packageNames) {
|
|
||||||
final Intent launchIntent = new Intent(Intent.ACTION_MAIN, null);
|
|
||||||
launchIntent.addCategory(Intent.CATEGORY_LAUNCHER);
|
|
||||||
|
|
||||||
// If we do not specify MATCH_DIRECT_BOOT_AWARE or
|
|
||||||
// MATCH_DIRECT_BOOT_UNAWARE, system will derive and update the flags
|
|
||||||
// according to the user's lock state. When the user is locked,
|
|
||||||
// components
|
|
||||||
// with ComponentInfo#directBootAware == false will be filtered. We should
|
|
||||||
// explicitly include both direct boot aware and unaware components here.
|
|
||||||
final List<ResolveInfo> resolveInfos =
|
|
||||||
mPackageManager.queryIntentActivities(
|
|
||||||
launchIntent,
|
|
||||||
PackageManager.MATCH_DISABLED_COMPONENTS
|
|
||||||
| PackageManager.MATCH_DIRECT_BOOT_AWARE
|
|
||||||
| PackageManager.MATCH_DIRECT_BOOT_UNAWARE
|
|
||||||
| PackageManager.MATCH_SYSTEM_ONLY);
|
|
||||||
for (int i = 0, size = resolveInfos.size(); i < size; i++) {
|
|
||||||
final ResolveInfo resolveInfo = resolveInfos.get(i);
|
|
||||||
if (ArrayUtils.contains(packageNames, resolveInfo.activityInfo.packageName)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return version number of an app represented by {@code packageName}, and return -1 if not
|
* Return version number of an app represented by {@code packageName}, and return -1 if not
|
||||||
* found.
|
* found.
|
||||||
|
@@ -1,38 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
/** Model class to parse and store anomaly info from statsd. */
|
|
||||||
public class AnomalyInfo {
|
|
||||||
private static final String TAG = "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) {
|
|
||||||
Log.i(TAG, "anomalyInfo: " + info);
|
|
||||||
KeyValueListParser parser = new KeyValueListParser(',');
|
|
||||||
parser.setString(info);
|
|
||||||
anomalyType = parser.getInt(KEY_ANOMALY_TYPE, -1);
|
|
||||||
autoRestriction = parser.getBoolean(KEY_AUTO_RESTRICTION, false);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -40,20 +40,16 @@ import android.content.BroadcastReceiver;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
import android.content.pm.ActivityInfo;
|
|
||||||
import android.content.pm.ApplicationInfo;
|
import android.content.pm.ApplicationInfo;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.pm.ResolveInfo;
|
|
||||||
import android.os.BatteryConsumer;
|
import android.os.BatteryConsumer;
|
||||||
import android.os.BatteryStats;
|
import android.os.BatteryStats;
|
||||||
import android.os.BatteryStatsManager;
|
import android.os.BatteryStatsManager;
|
||||||
import android.os.BatteryUsageStats;
|
import android.os.BatteryUsageStats;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Process;
|
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
|
|
||||||
import com.android.settings.fuelgauge.batterytip.AnomalyDatabaseHelper;
|
import com.android.settings.fuelgauge.batterytip.AnomalyDatabaseHelper;
|
||||||
import com.android.settings.fuelgauge.batterytip.AnomalyInfo;
|
|
||||||
import com.android.settings.fuelgauge.batterytip.BatteryDatabaseManager;
|
import com.android.settings.fuelgauge.batterytip.BatteryDatabaseManager;
|
||||||
import com.android.settings.testutils.FakeFeatureFactory;
|
import com.android.settings.testutils.FakeFeatureFactory;
|
||||||
import com.android.settings.testutils.shadow.ShadowThreadUtils;
|
import com.android.settings.testutils.shadow.ShadowThreadUtils;
|
||||||
@@ -70,9 +66,6 @@ import org.mockito.MockitoAnnotations;
|
|||||||
import org.robolectric.RobolectricTestRunner;
|
import org.robolectric.RobolectricTestRunner;
|
||||||
import org.robolectric.RuntimeEnvironment;
|
import org.robolectric.RuntimeEnvironment;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@RunWith(RobolectricTestRunner.class)
|
@RunWith(RobolectricTestRunner.class)
|
||||||
public class BatteryUtilsTest {
|
public class BatteryUtilsTest {
|
||||||
|
|
||||||
@@ -122,7 +115,6 @@ public class BatteryUtilsTest {
|
|||||||
@Mock private ApplicationInfo mLowApplicationInfo;
|
@Mock private ApplicationInfo mLowApplicationInfo;
|
||||||
@Mock private PowerAllowlistBackend mPowerAllowlistBackend;
|
@Mock private PowerAllowlistBackend mPowerAllowlistBackend;
|
||||||
@Mock private BatteryDatabaseManager mBatteryDatabaseManager;
|
@Mock private BatteryDatabaseManager mBatteryDatabaseManager;
|
||||||
private AnomalyInfo mAnomalyInfo;
|
|
||||||
private BatteryUtils mBatteryUtils;
|
private BatteryUtils mBatteryUtils;
|
||||||
private FakeFeatureFactory mFeatureFactory;
|
private FakeFeatureFactory mFeatureFactory;
|
||||||
private PowerUsageFeatureProvider mProvider;
|
private PowerUsageFeatureProvider mProvider;
|
||||||
@@ -169,7 +161,6 @@ public class BatteryUtilsTest {
|
|||||||
doReturn(0L)
|
doReturn(0L)
|
||||||
.when(mBatteryUtils)
|
.when(mBatteryUtils)
|
||||||
.getForegroundServiceTotalTimeUs(any(BatteryStats.Uid.class), anyLong());
|
.getForegroundServiceTotalTimeUs(any(BatteryStats.Uid.class), anyLong());
|
||||||
mAnomalyInfo = new AnomalyInfo(INFO_WAKELOCK);
|
|
||||||
|
|
||||||
BatteryDatabaseManager.setUpForTest(mBatteryDatabaseManager);
|
BatteryDatabaseManager.setUpForTest(mBatteryDatabaseManager);
|
||||||
ShadowThreadUtils.setIsMainThread(true);
|
ShadowThreadUtils.setIsMainThread(true);
|
||||||
@@ -390,79 +381,6 @@ public class BatteryUtilsTest {
|
|||||||
assertThat(mBatteryUtils.isForceAppStandbyEnabled(UID, PACKAGE_NAME)).isFalse();
|
assertThat(mBatteryUtils.isForceAppStandbyEnabled(UID, PACKAGE_NAME)).isFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testShouldHideAnomaly_systemAppWithLauncher_returnTrue() {
|
|
||||||
final List<ResolveInfo> resolveInfos = new ArrayList<>();
|
|
||||||
final ResolveInfo resolveInfo = new ResolveInfo();
|
|
||||||
resolveInfo.activityInfo = new ActivityInfo();
|
|
||||||
resolveInfo.activityInfo.packageName = HIGH_SDK_PACKAGE;
|
|
||||||
|
|
||||||
doReturn(resolveInfos).when(mPackageManager).queryIntentActivities(any(), anyInt());
|
|
||||||
doReturn(new String[] {HIGH_SDK_PACKAGE}).when(mPackageManager).getPackagesForUid(UID);
|
|
||||||
mHighApplicationInfo.flags = ApplicationInfo.FLAG_SYSTEM;
|
|
||||||
|
|
||||||
assertThat(mBatteryUtils.shouldHideAnomaly(mPowerAllowlistBackend, UID, mAnomalyInfo))
|
|
||||||
.isTrue();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testShouldHideAnomaly_systemAppWithoutLauncher_returnTrue() {
|
|
||||||
doReturn(new ArrayList<>()).when(mPackageManager).queryIntentActivities(any(), anyInt());
|
|
||||||
doReturn(new String[] {HIGH_SDK_PACKAGE}).when(mPackageManager).getPackagesForUid(UID);
|
|
||||||
mHighApplicationInfo.flags = ApplicationInfo.FLAG_SYSTEM;
|
|
||||||
|
|
||||||
assertThat(mBatteryUtils.shouldHideAnomaly(mPowerAllowlistBackend, UID, mAnomalyInfo))
|
|
||||||
.isTrue();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testShouldHideAnomaly_systemUid_returnTrue() {
|
|
||||||
final int systemUid = Process.ROOT_UID;
|
|
||||||
doReturn(new String[] {HIGH_SDK_PACKAGE})
|
|
||||||
.when(mPackageManager)
|
|
||||||
.getPackagesForUid(systemUid);
|
|
||||||
|
|
||||||
assertThat(mBatteryUtils.shouldHideAnomaly(mPowerAllowlistBackend, systemUid, mAnomalyInfo))
|
|
||||||
.isTrue();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testShouldHideAnomaly_AppInDozeList_returnTrue() {
|
|
||||||
doReturn(new String[] {HIGH_SDK_PACKAGE}).when(mPackageManager).getPackagesForUid(UID);
|
|
||||||
doReturn(true)
|
|
||||||
.when(mPowerAllowlistBackend)
|
|
||||||
.isAllowlisted(new String[] {HIGH_SDK_PACKAGE}, UID);
|
|
||||||
|
|
||||||
assertThat(mBatteryUtils.shouldHideAnomaly(mPowerAllowlistBackend, UID, mAnomalyInfo))
|
|
||||||
.isTrue();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testShouldHideAnomaly_normalApp_returnFalse() {
|
|
||||||
doReturn(new String[] {HIGH_SDK_PACKAGE}).when(mPackageManager).getPackagesForUid(UID);
|
|
||||||
|
|
||||||
assertThat(mBatteryUtils.shouldHideAnomaly(mPowerAllowlistBackend, UID, mAnomalyInfo))
|
|
||||||
.isFalse();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testShouldHideAnomaly_excessivePriorOApp_returnFalse() {
|
|
||||||
doReturn(new String[] {LOW_SDK_PACKAGE}).when(mPackageManager).getPackagesForUid(UID);
|
|
||||||
mAnomalyInfo = new AnomalyInfo(INFO_EXCESSIVE);
|
|
||||||
|
|
||||||
assertThat(mBatteryUtils.shouldHideAnomaly(mPowerAllowlistBackend, UID, mAnomalyInfo))
|
|
||||||
.isFalse();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testShouldHideAnomaly_excessiveOApp_returnTrue() {
|
|
||||||
doReturn(new String[] {HIGH_SDK_PACKAGE}).when(mPackageManager).getPackagesForUid(UID);
|
|
||||||
mAnomalyInfo = new AnomalyInfo(INFO_EXCESSIVE);
|
|
||||||
|
|
||||||
assertThat(mBatteryUtils.shouldHideAnomaly(mPowerAllowlistBackend, UID, mAnomalyInfo))
|
|
||||||
.isTrue();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void clearForceAppStandby_appRestricted_clearAndReturnTrue() {
|
public void clearForceAppStandby_appRestricted_clearAndReturnTrue() {
|
||||||
when(mBatteryUtils.getPackageUid(HIGH_SDK_PACKAGE)).thenReturn(UID);
|
when(mBatteryUtils.getPackageUid(HIGH_SDK_PACKAGE)).thenReturn(UID);
|
||||||
|
@@ -74,6 +74,7 @@ import com.android.settingslib.search.SearchIndexableRaw;
|
|||||||
|
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
import org.junit.Ignore;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.mockito.AdditionalMatchers;
|
import org.mockito.AdditionalMatchers;
|
||||||
@@ -709,6 +710,7 @@ public class UserSettingsTest {
|
|||||||
verify(mUserManager).getAliveUsers();
|
verify(mUserManager).getAliveUsers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Ignore
|
||||||
@Test
|
@Test
|
||||||
public void updateUserList_userIconMissing_shouldLoadIcon() {
|
public void updateUserList_userIconMissing_shouldLoadIcon() {
|
||||||
UserInfo currentUser = getAdminUser(true);
|
UserInfo currentUser = getAdminUser(true);
|
||||||
|
Reference in New Issue
Block a user