diff --git a/src/com/android/settings/fuelgauge/batterytip/detectors/RestrictAppDetector.java b/src/com/android/settings/fuelgauge/batterytip/detectors/RestrictAppDetector.java index 017cd3fbede..5a640e56c4f 100644 --- a/src/com/android/settings/fuelgauge/batterytip/detectors/RestrictAppDetector.java +++ b/src/com/android/settings/fuelgauge/batterytip/detectors/RestrictAppDetector.java @@ -25,6 +25,7 @@ import com.android.settings.fuelgauge.batterytip.AnomalyDatabaseHelper; import com.android.settings.fuelgauge.batterytip.AppInfo; import com.android.settings.fuelgauge.batterytip.BatteryDatabaseManager; import com.android.settings.fuelgauge.batterytip.BatteryTipPolicy; +import com.android.settings.fuelgauge.batterytip.tips.AppInfoPredicate; import com.android.settings.fuelgauge.batterytip.tips.BatteryTip; import com.android.settings.fuelgauge.batterytip.tips.RestrictAppTip; @@ -44,17 +45,13 @@ public class RestrictAppDetector implements BatteryTipDetector { BatteryDatabaseManager mBatteryDatabaseManager; private Context mContext; - private Predicate mAppInfoPredicate = new Predicate() { - @Override - public boolean test(AppInfo appInfo) { - return Utils.getApplicationLabel(mContext, appInfo.packageName) == null; - } - }; + private AppInfoPredicate mAppInfoPredicate; public RestrictAppDetector(Context context, BatteryTipPolicy policy) { mContext = context; mPolicy = policy; mBatteryDatabaseManager = BatteryDatabaseManager.getInstance(context); + mAppInfoPredicate = new AppInfoPredicate(context); } @Override diff --git a/src/com/android/settings/fuelgauge/batterytip/tips/AppInfoPredicate.java b/src/com/android/settings/fuelgauge/batterytip/tips/AppInfoPredicate.java new file mode 100644 index 00000000000..df78caaf4a8 --- /dev/null +++ b/src/com/android/settings/fuelgauge/batterytip/tips/AppInfoPredicate.java @@ -0,0 +1,46 @@ +/* + * 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.tips; + +import android.app.AppOpsManager; +import android.content.Context; + +import com.android.settings.Utils; +import com.android.settings.fuelgauge.batterytip.AppInfo; + +import java.util.function.Predicate; + +/** + * {@link Predicate} for {@link AppInfo} to check whether it has label or restricted. + */ +public class AppInfoPredicate implements Predicate { + private Context mContext; + private AppOpsManager mAppOpsManager; + + public AppInfoPredicate(Context context) { + mContext = context; + mAppOpsManager = context.getSystemService(AppOpsManager.class); + } + + @Override + public boolean test(AppInfo appInfo) { + // Return true if app doesn't have label or already been restricted + return Utils.getApplicationLabel(mContext, appInfo.packageName) == null + || mAppOpsManager.checkOpNoThrow(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, + appInfo.uid, appInfo.packageName) == AppOpsManager.MODE_IGNORED; + } +} diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/RestrictAppDetectorTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/RestrictAppDetectorTest.java index 23f08c0a6e4..76e2928cb9d 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/RestrictAppDetectorTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/RestrictAppDetectorTest.java @@ -26,6 +26,7 @@ import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.spy; +import android.app.AppOpsManager; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; @@ -53,8 +54,10 @@ import java.util.List; @RunWith(SettingsRobolectricTestRunner.class) public class RestrictAppDetectorTest { + private static final int RESTRICTED_UID = 222; private static final String PACKAGE_NAME = "com.android.app"; private static final String UNINSTALLED_PACKAGE_NAME = "com.android.uninstalled"; + private static final String RESTRICTED_PACKAGE_NAME = "com.android.restricted"; private Context mContext; private BatteryTipPolicy mPolicy; private RestrictAppDetector mRestrictAppDetector; @@ -66,6 +69,8 @@ public class RestrictAppDetectorTest { private PackageManager mPackageManager; @Mock private ApplicationInfo mApplicationInfo; + @Mock + private AppOpsManager mAppOpsManager; @Before public void setUp() throws PackageManager.NameNotFoundException { @@ -79,8 +84,10 @@ public class RestrictAppDetectorTest { mContext = spy(RuntimeEnvironment.application); mPolicy = spy(new BatteryTipPolicy(mContext)); - mRestrictAppDetector = new RestrictAppDetector(mContext, mPolicy); - mRestrictAppDetector.mBatteryDatabaseManager = mBatteryDatabaseManager; + + doReturn(mAppOpsManager).when(mContext).getSystemService(AppOpsManager.class); + doReturn(AppOpsManager.MODE_IGNORED).when(mAppOpsManager).checkOpNoThrow( + AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, RESTRICTED_UID, RESTRICTED_PACKAGE_NAME); doReturn(mPackageManager).when(mContext).getPackageManager(); doReturn(mApplicationInfo).when(mPackageManager).getApplicationInfo(eq(PACKAGE_NAME), @@ -88,6 +95,10 @@ public class RestrictAppDetectorTest { doReturn(PACKAGE_NAME).when(mApplicationInfo).loadLabel(any()); doThrow(new PackageManager.NameNotFoundException()).when( mPackageManager).getApplicationInfo(eq(UNINSTALLED_PACKAGE_NAME), anyInt()); + + mRestrictAppDetector = new RestrictAppDetector(mContext, mPolicy); + mRestrictAppDetector.mBatteryDatabaseManager = mBatteryDatabaseManager; + } @After @@ -127,6 +138,23 @@ public class RestrictAppDetectorTest { assertThat(restrictAppTip.getRestrictAppList()).containsExactly(mAppInfo); } + @Test + public void testDetect_hasRestrictedAnomaly_removeIt() throws + PackageManager.NameNotFoundException { + mAppInfoList.add(new AppInfo.Builder() + .setUid(RESTRICTED_UID) + .setPackageName(RESTRICTED_PACKAGE_NAME) + .build()); + doReturn(mAppInfoList).when(mBatteryDatabaseManager) + .queryAllAnomalies(anyLong(), eq(AnomalyDatabaseHelper.State.NEW)); + doReturn(mApplicationInfo).when(mPackageManager).getApplicationInfo( + eq(RESTRICTED_PACKAGE_NAME), anyInt()); + + final RestrictAppTip restrictAppTip = (RestrictAppTip) mRestrictAppDetector.detect(); + assertThat(restrictAppTip.getState()).isEqualTo(BatteryTip.StateType.NEW); + assertThat(restrictAppTip.getRestrictAppList()).containsExactly(mAppInfo); + } + @Test public void testDetect_noAnomaly_tipInvisible() { doReturn(new ArrayList()).when(mBatteryDatabaseManager)