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.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.os.BatteryManager;
|
||||
import android.os.BatteryStats;
|
||||
import android.os.BatteryStatsManager;
|
||||
import android.os.BatteryUsageStats;
|
||||
import android.os.BatteryUsageStatsQuery;
|
||||
import android.os.Build;
|
||||
import android.os.Process;
|
||||
import android.os.SystemClock;
|
||||
import android.os.UidBatteryConsumer;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
import android.text.TextUtils;
|
||||
import android.text.format.DateUtils;
|
||||
@@ -47,14 +44,11 @@ import androidx.annotation.WorkerThread;
|
||||
import com.android.internal.util.ArrayUtils;
|
||||
import com.android.settings.R;
|
||||
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.StatsManagerConfig;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
import com.android.settingslib.applications.AppUtils;
|
||||
import com.android.settingslib.fuelgauge.Estimate;
|
||||
import com.android.settingslib.fuelgauge.EstimateKt;
|
||||
import com.android.settingslib.fuelgauge.PowerAllowlistBackend;
|
||||
import com.android.settingslib.utils.PowerUtil;
|
||||
import com.android.settingslib.utils.StringUtil;
|
||||
import com.android.settingslib.utils.ThreadUtils;
|
||||
@@ -68,7 +62,6 @@ import java.time.Instant;
|
||||
import java.time.ZoneId;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.format.FormatStyle;
|
||||
import java.util.List;
|
||||
|
||||
/** Utils for battery operation */
|
||||
public class BatteryUtils {
|
||||
@@ -548,74 +541,6 @@ public class BatteryUtils {
|
||||
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
|
||||
* 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.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.os.BatteryConsumer;
|
||||
import android.os.BatteryStats;
|
||||
import android.os.BatteryStatsManager;
|
||||
import android.os.BatteryUsageStats;
|
||||
import android.os.Build;
|
||||
import android.os.Process;
|
||||
import android.os.SystemClock;
|
||||
|
||||
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.testutils.FakeFeatureFactory;
|
||||
import com.android.settings.testutils.shadow.ShadowThreadUtils;
|
||||
@@ -70,9 +66,6 @@ import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class BatteryUtilsTest {
|
||||
|
||||
@@ -122,7 +115,6 @@ public class BatteryUtilsTest {
|
||||
@Mock private ApplicationInfo mLowApplicationInfo;
|
||||
@Mock private PowerAllowlistBackend mPowerAllowlistBackend;
|
||||
@Mock private BatteryDatabaseManager mBatteryDatabaseManager;
|
||||
private AnomalyInfo mAnomalyInfo;
|
||||
private BatteryUtils mBatteryUtils;
|
||||
private FakeFeatureFactory mFeatureFactory;
|
||||
private PowerUsageFeatureProvider mProvider;
|
||||
@@ -169,7 +161,6 @@ public class BatteryUtilsTest {
|
||||
doReturn(0L)
|
||||
.when(mBatteryUtils)
|
||||
.getForegroundServiceTotalTimeUs(any(BatteryStats.Uid.class), anyLong());
|
||||
mAnomalyInfo = new AnomalyInfo(INFO_WAKELOCK);
|
||||
|
||||
BatteryDatabaseManager.setUpForTest(mBatteryDatabaseManager);
|
||||
ShadowThreadUtils.setIsMainThread(true);
|
||||
@@ -390,79 +381,6 @@ public class BatteryUtilsTest {
|
||||
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
|
||||
public void clearForceAppStandby_appRestricted_clearAndReturnTrue() {
|
||||
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.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.AdditionalMatchers;
|
||||
@@ -709,6 +710,7 @@ public class UserSettingsTest {
|
||||
verify(mUserManager).getAliveUsers();
|
||||
}
|
||||
|
||||
@Ignore
|
||||
@Test
|
||||
public void updateUserList_userIconMissing_shouldLoadIcon() {
|
||||
UserInfo currentUser = getAdminUser(true);
|
||||
|
Reference in New Issue
Block a user