Merge "Fix bugs in auto restriction." into pi-dev am: f6e2c19fcc

am: a9e4d4a42a

Change-Id: If82969696eb492ea3875a0e0fb92f038024f00f9
This commit is contained in:
Lei Yu
2018-04-23 10:13:31 -07:00
committed by android-build-merger
14 changed files with 234 additions and 51 deletions

View File

@@ -43,7 +43,6 @@ public class RestrictAppPreferenceController extends BasePreferenceController {
@VisibleForTesting @VisibleForTesting
List<AppInfo> mAppInfos; List<AppInfo> mAppInfos;
private AppOpsManager mAppOpsManager; private AppOpsManager mAppOpsManager;
private SettingsActivity mSettingsActivity;
private InstrumentedPreferenceFragment mPreferenceFragment; private InstrumentedPreferenceFragment mPreferenceFragment;
private UserManager mUserManager; private UserManager mUserManager;
@@ -53,10 +52,8 @@ public class RestrictAppPreferenceController extends BasePreferenceController {
mUserManager = context.getSystemService(UserManager.class); mUserManager = context.getSystemService(UserManager.class);
} }
public RestrictAppPreferenceController(SettingsActivity settingsActivity, public RestrictAppPreferenceController(InstrumentedPreferenceFragment preferenceFragment) {
InstrumentedPreferenceFragment preferenceFragment) { this(preferenceFragment.getContext());
this(settingsActivity.getApplicationContext());
mSettingsActivity = settingsActivity;
mPreferenceFragment = preferenceFragment; mPreferenceFragment = preferenceFragment;
} }
@@ -83,7 +80,7 @@ public class RestrictAppPreferenceController extends BasePreferenceController {
public boolean handlePreferenceTreeClick(Preference preference) { public boolean handlePreferenceTreeClick(Preference preference) {
if (getPreferenceKey().equals(preference.getKey())) { if (getPreferenceKey().equals(preference.getKey())) {
// start fragment // start fragment
RestrictedAppDetails.startRestrictedAppDetails(mSettingsActivity, mPreferenceFragment, RestrictedAppDetails.startRestrictedAppDetails(mPreferenceFragment,
mAppInfos); mAppInfos);
return true; return true;
} }

View File

@@ -67,12 +67,12 @@ public class RestrictedAppDetails extends DashboardFragment {
private final FooterPreferenceMixin mFooterPreferenceMixin = private final FooterPreferenceMixin mFooterPreferenceMixin =
new FooterPreferenceMixin(this, getLifecycle()); new FooterPreferenceMixin(this, getLifecycle());
public static void startRestrictedAppDetails(SettingsActivity caller, public static void startRestrictedAppDetails(InstrumentedPreferenceFragment fragment,
InstrumentedPreferenceFragment fragment, List<AppInfo> appInfos) { List<AppInfo> appInfos) {
final Bundle args = new Bundle(); final Bundle args = new Bundle();
args.putParcelableList(EXTRA_APP_INFO_LIST, appInfos); args.putParcelableList(EXTRA_APP_INFO_LIST, appInfos);
new SubSettingLauncher(caller) new SubSettingLauncher(fragment.getContext())
.setDestination(RestrictedAppDetails.class.getName()) .setDestination(RestrictedAppDetails.class.getName())
.setArguments(args) .setArguments(args)
.setTitle(R.string.restricted_app_title) .setTitle(R.string.restricted_app_title)

View File

@@ -73,7 +73,7 @@ public class SmartBatterySettings extends DashboardFragment {
controllers.add(new SmartBatteryPreferenceController(context)); controllers.add(new SmartBatteryPreferenceController(context));
if (settingsActivity != null && fragment != null) { if (settingsActivity != null && fragment != null) {
controllers.add( controllers.add(
new RestrictAppPreferenceController(settingsActivity, fragment)); new RestrictAppPreferenceController(fragment));
} else { } else {
controllers.add(new RestrictAppPreferenceController(context)); controllers.add(new RestrictAppPreferenceController(context));
} }

View File

@@ -100,6 +100,7 @@ public class AnomalyDetectionJobService extends JobService {
.getFactory(this).getPowerUsageFeatureProvider(this); .getFactory(this).getPowerUsageFeatureProvider(this);
final MetricsFeatureProvider metricsFeatureProvider = FeatureFactory final MetricsFeatureProvider metricsFeatureProvider = FeatureFactory
.getFactory(this).getMetricsFeatureProvider(); .getFactory(this).getMetricsFeatureProvider();
batteryUtils.initBatteryStatsHelper(batteryStatsHelper, null /* bundle */, userManager);
for (JobWorkItem item = params.dequeueWork(); item != null; for (JobWorkItem item = params.dequeueWork(); item != null;
item = params.dequeueWork()) { item = params.dequeueWork()) {

View File

@@ -101,8 +101,7 @@ public class BatteryTipUtils {
} }
case BatteryTip.TipType.APP_RESTRICTION: case BatteryTip.TipType.APP_RESTRICTION:
if (batteryTip.getState() == BatteryTip.StateType.HANDLED) { if (batteryTip.getState() == BatteryTip.StateType.HANDLED) {
return new OpenRestrictAppFragmentAction(settingsActivity, fragment, return new OpenRestrictAppFragmentAction(fragment, (RestrictAppTip) batteryTip);
(RestrictAppTip) batteryTip);
} else { } else {
return new RestrictAppAction(settingsActivity, (RestrictAppTip) batteryTip); return new RestrictAppAction(settingsActivity, (RestrictAppTip) batteryTip);
} }

View File

@@ -16,15 +16,16 @@
package com.android.settings.fuelgauge.batterytip.actions; package com.android.settings.fuelgauge.batterytip.actions;
import android.app.Fragment; import android.support.annotation.VisibleForTesting;
import com.android.internal.logging.nano.MetricsProto; import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.SettingsActivity;
import com.android.settings.core.InstrumentedPreferenceFragment; import com.android.settings.core.InstrumentedPreferenceFragment;
import com.android.settings.fuelgauge.BatteryUtils;
import com.android.settings.fuelgauge.RestrictedAppDetails; import com.android.settings.fuelgauge.RestrictedAppDetails;
import com.android.settings.fuelgauge.batterytip.AnomalyDatabaseHelper;
import com.android.settings.fuelgauge.batterytip.AppInfo; import com.android.settings.fuelgauge.batterytip.AppInfo;
import com.android.settings.fuelgauge.batterytip.BatteryDatabaseManager;
import com.android.settings.fuelgauge.batterytip.tips.RestrictAppTip; import com.android.settings.fuelgauge.batterytip.tips.RestrictAppTip;
import com.android.settingslib.utils.ThreadUtils;
import java.util.List; import java.util.List;
@@ -33,17 +34,16 @@ import java.util.List;
*/ */
public class OpenRestrictAppFragmentAction extends BatteryTipAction { public class OpenRestrictAppFragmentAction extends BatteryTipAction {
private final RestrictAppTip mRestrictAppTip; private final RestrictAppTip mRestrictAppTip;
private final BatteryUtils mBatteryUtils;
private final SettingsActivity mSettingsActivity;
private final InstrumentedPreferenceFragment mFragment; private final InstrumentedPreferenceFragment mFragment;
@VisibleForTesting
BatteryDatabaseManager mBatteryDatabaseManager;
public OpenRestrictAppFragmentAction(SettingsActivity settingsActivity, public OpenRestrictAppFragmentAction(InstrumentedPreferenceFragment fragment,
InstrumentedPreferenceFragment fragment, RestrictAppTip tip) { RestrictAppTip tip) {
super(fragment.getContext()); super(fragment.getContext());
mSettingsActivity = settingsActivity;
mFragment = fragment; mFragment = fragment;
mRestrictAppTip = tip; mRestrictAppTip = tip;
mBatteryUtils = BatteryUtils.getInstance(mContext); mBatteryDatabaseManager = BatteryDatabaseManager.getInstance(mContext);
} }
/** /**
@@ -54,7 +54,10 @@ public class OpenRestrictAppFragmentAction extends BatteryTipAction {
mMetricsFeatureProvider.action(mContext, mMetricsFeatureProvider.action(mContext,
MetricsProto.MetricsEvent.ACTION_TIP_OPEN_APP_RESTRICTION_PAGE, metricsKey); MetricsProto.MetricsEvent.ACTION_TIP_OPEN_APP_RESTRICTION_PAGE, metricsKey);
final List<AppInfo> mAppInfos = mRestrictAppTip.getRestrictAppList(); final List<AppInfo> mAppInfos = mRestrictAppTip.getRestrictAppList();
RestrictedAppDetails.startRestrictedAppDetails(mSettingsActivity, mFragment, RestrictedAppDetails.startRestrictedAppDetails(mFragment, mAppInfos);
mAppInfos);
// Mark all the anomalies as handled, so it won't show up again.
ThreadUtils.postOnBackgroundThread(() -> mBatteryDatabaseManager.updateAnomalies(mAppInfos,
AnomalyDatabaseHelper.State.HANDLED));
} }
} }

View File

@@ -20,18 +20,17 @@ import android.content.Context;
import androidx.annotation.VisibleForTesting; import androidx.annotation.VisibleForTesting;
import android.text.format.DateUtils; import android.text.format.DateUtils;
import com.android.settings.Utils;
import com.android.settings.fuelgauge.batterytip.AnomalyDatabaseHelper; import com.android.settings.fuelgauge.batterytip.AnomalyDatabaseHelper;
import com.android.settings.fuelgauge.batterytip.AppInfo; import com.android.settings.fuelgauge.batterytip.AppInfo;
import com.android.settings.fuelgauge.batterytip.BatteryDatabaseManager; import com.android.settings.fuelgauge.batterytip.BatteryDatabaseManager;
import com.android.settings.fuelgauge.batterytip.BatteryTipPolicy; import com.android.settings.fuelgauge.batterytip.BatteryTipPolicy;
import com.android.settings.fuelgauge.batterytip.tips.AppInfoPredicate; import com.android.settings.fuelgauge.batterytip.tips.AppLabelPredicate;
import com.android.settings.fuelgauge.batterytip.tips.AppRestrictionPredicate;
import com.android.settings.fuelgauge.batterytip.tips.BatteryTip; import com.android.settings.fuelgauge.batterytip.tips.BatteryTip;
import com.android.settings.fuelgauge.batterytip.tips.RestrictAppTip; import com.android.settings.fuelgauge.batterytip.tips.RestrictAppTip;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.function.Predicate;
/** /**
* Detector whether to show summary tip. This detector should be executed as the last * Detector whether to show summary tip. This detector should be executed as the last
@@ -45,13 +44,15 @@ public class RestrictAppDetector implements BatteryTipDetector {
BatteryDatabaseManager mBatteryDatabaseManager; BatteryDatabaseManager mBatteryDatabaseManager;
private Context mContext; private Context mContext;
private AppInfoPredicate mAppInfoPredicate; private AppRestrictionPredicate mAppRestrictionPredicate;
private AppLabelPredicate mAppLabelPredicate;
public RestrictAppDetector(Context context, BatteryTipPolicy policy) { public RestrictAppDetector(Context context, BatteryTipPolicy policy) {
mContext = context; mContext = context;
mPolicy = policy; mPolicy = policy;
mBatteryDatabaseManager = BatteryDatabaseManager.getInstance(context); mBatteryDatabaseManager = BatteryDatabaseManager.getInstance(context);
mAppInfoPredicate = new AppInfoPredicate(context); mAppRestrictionPredicate = new AppRestrictionPredicate(context);
mAppLabelPredicate = new AppLabelPredicate(context);
} }
@Override @Override
@@ -64,7 +65,8 @@ public class RestrictAppDetector implements BatteryTipDetector {
final long oneDayBeforeMs = System.currentTimeMillis() - DateUtils.DAY_IN_MILLIS; final long oneDayBeforeMs = System.currentTimeMillis() - DateUtils.DAY_IN_MILLIS;
final List<AppInfo> highUsageApps = mBatteryDatabaseManager.queryAllAnomalies( final List<AppInfo> highUsageApps = mBatteryDatabaseManager.queryAllAnomalies(
oneDayBeforeMs, AnomalyDatabaseHelper.State.NEW); oneDayBeforeMs, AnomalyDatabaseHelper.State.NEW);
highUsageApps.removeIf(mAppInfoPredicate); // Remove it if it doesn't have label or been restricted
highUsageApps.removeIf(mAppLabelPredicate.or(mAppRestrictionPredicate));
if (!highUsageApps.isEmpty()) { if (!highUsageApps.isEmpty()) {
// If there are new anomalies, show them // If there are new anomalies, show them
return new RestrictAppTip(BatteryTip.StateType.NEW, highUsageApps); return new RestrictAppTip(BatteryTip.StateType.NEW, highUsageApps);
@@ -72,7 +74,8 @@ public class RestrictAppDetector implements BatteryTipDetector {
// Otherwise, show auto-handled one if it exists // Otherwise, show auto-handled one if it exists
final List<AppInfo> autoHandledApps = mBatteryDatabaseManager.queryAllAnomalies( final List<AppInfo> autoHandledApps = mBatteryDatabaseManager.queryAllAnomalies(
oneDayBeforeMs, AnomalyDatabaseHelper.State.AUTO_HANDLED); oneDayBeforeMs, AnomalyDatabaseHelper.State.AUTO_HANDLED);
autoHandledApps.removeIf(mAppInfoPredicate); // Remove it if it doesn't have label or unrestricted
autoHandledApps.removeIf(mAppLabelPredicate.or(mAppRestrictionPredicate.negate()));
return new RestrictAppTip(autoHandledApps.isEmpty() ? BatteryTip.StateType.INVISIBLE return new RestrictAppTip(autoHandledApps.isEmpty() ? BatteryTip.StateType.INVISIBLE
: BatteryTip.StateType.HANDLED, autoHandledApps); : BatteryTip.StateType.HANDLED, autoHandledApps);
} }

View File

@@ -25,22 +25,20 @@ import com.android.settings.fuelgauge.batterytip.AppInfo;
import java.util.function.Predicate; import java.util.function.Predicate;
/** /**
* {@link Predicate} for {@link AppInfo} to check whether it has label or restricted. * {@link Predicate} for {@link AppInfo} to check whether it has label
*/ */
public class AppInfoPredicate implements Predicate<AppInfo> { public class AppLabelPredicate implements Predicate<AppInfo> {
private Context mContext; private Context mContext;
private AppOpsManager mAppOpsManager; private AppOpsManager mAppOpsManager;
public AppInfoPredicate(Context context) { public AppLabelPredicate(Context context) {
mContext = context; mContext = context;
mAppOpsManager = context.getSystemService(AppOpsManager.class); mAppOpsManager = context.getSystemService(AppOpsManager.class);
} }
@Override @Override
public boolean test(AppInfo appInfo) { public boolean test(AppInfo appInfo) {
// Return true if app doesn't have label or already been restricted // Return true if app doesn't have label
return Utils.getApplicationLabel(mContext, appInfo.packageName) == null return Utils.getApplicationLabel(mContext, appInfo.packageName) == null;
|| mAppOpsManager.checkOpNoThrow(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND,
appInfo.uid, appInfo.packageName) == AppOpsManager.MODE_IGNORED;
} }
} }

View File

@@ -0,0 +1,43 @@
/*
* 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 is restricted.
*/
public class AppRestrictionPredicate implements Predicate<AppInfo> {
private AppOpsManager mAppOpsManager;
public AppRestrictionPredicate(Context context) {
mAppOpsManager = context.getSystemService(AppOpsManager.class);
}
@Override
public boolean test(AppInfo appInfo) {
// Return true if app already been restricted
return mAppOpsManager.checkOpNoThrow(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND,
appInfo.uid, appInfo.packageName) == AppOpsManager.MODE_IGNORED;
}
}

View File

@@ -67,8 +67,6 @@ public class RestrictAppPreferenceControllerTest {
@Mock @Mock
private AppOpsManager.PackageOps mOtherUserPackageOps; private AppOpsManager.PackageOps mOtherUserPackageOps;
@Mock @Mock
private SettingsActivity mSettingsActivity;
@Mock
private InstrumentedPreferenceFragment mFragment; private InstrumentedPreferenceFragment mFragment;
@Mock @Mock
private UserManager mUserManager; private UserManager mUserManager;
@@ -102,9 +100,9 @@ public class RestrictAppPreferenceControllerTest {
mContext = spy(RuntimeEnvironment.application); mContext = spy(RuntimeEnvironment.application);
doReturn(mAppOpsManager).when(mContext).getSystemService(Context.APP_OPS_SERVICE); doReturn(mAppOpsManager).when(mContext).getSystemService(Context.APP_OPS_SERVICE);
doReturn(mUserManager).when(mContext).getSystemService(UserManager.class); doReturn(mUserManager).when(mContext).getSystemService(UserManager.class);
doReturn(mContext).when(mSettingsActivity).getApplicationContext(); doReturn(mContext).when(mFragment).getContext();
mRestrictAppPreferenceController = mRestrictAppPreferenceController =
new RestrictAppPreferenceController(mSettingsActivity, mFragment); new RestrictAppPreferenceController(mFragment);
mPackageOpsList = new ArrayList<>(); mPackageOpsList = new ArrayList<>();
mPreference = new Preference(mContext); mPreference = new Preference(mContext);
mPreference.setKey(mRestrictAppPreferenceController.getPreferenceKey()); mPreference.setKey(mRestrictAppPreferenceController.getPreferenceKey());
@@ -171,7 +169,7 @@ public class RestrictAppPreferenceControllerTest {
mRestrictAppPreferenceController.handlePreferenceTreeClick(mPreference); mRestrictAppPreferenceController.handlePreferenceTreeClick(mPreference);
verify(mSettingsActivity).startActivity(intent.capture()); verify(mContext).startActivity(intent.capture());
assertThat(intent.getValue().getStringExtra(EXTRA_SHOW_FRAGMENT)) assertThat(intent.getValue().getStringExtra(EXTRA_SHOW_FRAGMENT))
.isEqualTo(RestrictedAppDetails.class.getName()); .isEqualTo(RestrictedAppDetails.class.getName());
assertThat(intent.getValue().getIntExtra(EXTRA_SHOW_FRAGMENT_TITLE_RESID, -1)) assertThat(intent.getValue().getIntExtra(EXTRA_SHOW_FRAGMENT_TITLE_RESID, -1))

View File

@@ -69,8 +69,6 @@ public class RestrictedAppDetailsTest {
@Mock(answer = Answers.RETURNS_DEEP_STUBS) @Mock(answer = Answers.RETURNS_DEEP_STUBS)
private PreferenceManager mPreferenceManager; private PreferenceManager mPreferenceManager;
@Mock @Mock
private SettingsActivity mSettingsActivity;
@Mock
private InstrumentedPreferenceFragment mFragment; private InstrumentedPreferenceFragment mFragment;
private RestrictedAppDetails mRestrictedAppDetails; private RestrictedAppDetails mRestrictedAppDetails;
private Context mContext; private Context mContext;
@@ -90,6 +88,7 @@ public class RestrictedAppDetailsTest {
doReturn(mPreferenceManager).when(mRestrictedAppDetails).getPreferenceManager(); doReturn(mPreferenceManager).when(mRestrictedAppDetails).getPreferenceManager();
doReturn(mContext).when(mPreferenceManager).getContext(); doReturn(mContext).when(mPreferenceManager).getContext();
doReturn(mContext).when(mFragment).getContext();
mRestrictedAppDetails.mPackageManager = mPackageManager; mRestrictedAppDetails.mPackageManager = mPackageManager;
mRestrictedAppDetails.mIconDrawableFactory = mIconDrawableFactory; mRestrictedAppDetails.mIconDrawableFactory = mIconDrawableFactory;
mRestrictedAppDetails.mAppInfos = new ArrayList<>(); mRestrictedAppDetails.mAppInfos = new ArrayList<>();
@@ -124,9 +123,9 @@ public class RestrictedAppDetailsTest {
// Get the intent in which it has the app info bundle // Get the intent in which it has the app info bundle
mIntent = captor.getValue(); mIntent = captor.getValue();
return true; return true;
}).when(mSettingsActivity).startActivity(captor.capture()); }).when(mContext).startActivity(captor.capture());
RestrictedAppDetails.startRestrictedAppDetails(mSettingsActivity, mFragment, RestrictedAppDetails.startRestrictedAppDetails(mFragment,
mRestrictedAppDetails.mAppInfos); mRestrictedAppDetails.mAppInfos);
final Bundle bundle = mIntent.getBundleExtra( final Bundle bundle = mIntent.getBundleExtra(

View File

@@ -0,0 +1,99 @@
/*
* 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.actions;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.Context;
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.core.InstrumentedPreferenceFragment;
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.tips.BatteryTip;
import com.android.settings.fuelgauge.batterytip.tips.RestrictAppTip;
import com.android.settings.testutils.DatabaseTestUtils;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import org.junit.After;
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 java.util.ArrayList;
import java.util.List;
@RunWith(SettingsRobolectricTestRunner.class)
public class OpenRestrictAppFragmentActionTest {
private static final String PACKAGE_NAME_1 = "com.android.app1";
private static final String PACKAGE_NAME_2 = "com.android.app2";
private static final int ANOMALY_WAKEUP = 0;
private static final int ANOMALY_BT = 1;
private static final int METRICS_KEY = 1;
@Mock
private InstrumentedPreferenceFragment mFragment;
@Mock
private BatteryDatabaseManager mBatteryDatabaseManager;
private OpenRestrictAppFragmentAction mAction;
private FakeFeatureFactory mFeatureFactory;
private Context mContext;
private List<AppInfo> mAppInfos;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = RuntimeEnvironment.application;
mAppInfos = new ArrayList<>();
mAppInfos.add(new AppInfo.Builder()
.setPackageName(PACKAGE_NAME_1)
.addAnomalyType(ANOMALY_BT)
.build());
mAppInfos.add(new AppInfo.Builder()
.setPackageName(PACKAGE_NAME_2)
.addAnomalyType(ANOMALY_WAKEUP)
.build());
mFeatureFactory = FakeFeatureFactory.setupForTest();
when(mFragment.getContext()).thenReturn(mContext);
mAction = new OpenRestrictAppFragmentAction(mFragment,
new RestrictAppTip(BatteryTip.StateType.HANDLED, mAppInfos));
mAction.mBatteryDatabaseManager = mBatteryDatabaseManager;
}
@After
public void cleanUp() {
DatabaseTestUtils.clearDb(mContext);
}
@Test
public void testHandlePositiveAction() {
mAction.handlePositiveAction(METRICS_KEY);
verify(mFeatureFactory.metricsFeatureProvider).action(mContext,
MetricsProto.MetricsEvent.ACTION_TIP_OPEN_APP_RESTRICTION_PAGE, METRICS_KEY);
verify(mBatteryDatabaseManager).updateAnomalies(mAppInfos,
AnomalyDatabaseHelper.State.HANDLED);
}
}

View File

@@ -55,9 +55,11 @@ import java.util.List;
public class RestrictAppDetectorTest { public class RestrictAppDetectorTest {
private static final int RESTRICTED_UID = 222; private static final int RESTRICTED_UID = 222;
private static final int UNRESTRICTED_UID = 333;
private static final String PACKAGE_NAME = "com.android.app"; private static final String PACKAGE_NAME = "com.android.app";
private static final String UNINSTALLED_PACKAGE_NAME = "com.android.uninstalled"; private static final String UNINSTALLED_PACKAGE_NAME = "com.android.uninstalled";
private static final String RESTRICTED_PACKAGE_NAME = "com.android.restricted"; private static final String RESTRICTED_PACKAGE_NAME = "com.android.restricted";
private static final String UNRESTRICTED_PACKAGE_NAME = "com.android.unrestricted";
private Context mContext; private Context mContext;
private BatteryTipPolicy mPolicy; private BatteryTipPolicy mPolicy;
private RestrictAppDetector mRestrictAppDetector; private RestrictAppDetector mRestrictAppDetector;
@@ -88,9 +90,12 @@ public class RestrictAppDetectorTest {
doReturn(mAppOpsManager).when(mContext).getSystemService(AppOpsManager.class); doReturn(mAppOpsManager).when(mContext).getSystemService(AppOpsManager.class);
doReturn(AppOpsManager.MODE_IGNORED).when(mAppOpsManager).checkOpNoThrow( doReturn(AppOpsManager.MODE_IGNORED).when(mAppOpsManager).checkOpNoThrow(
AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, RESTRICTED_UID, RESTRICTED_PACKAGE_NAME); AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, RESTRICTED_UID, RESTRICTED_PACKAGE_NAME);
doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager).checkOpNoThrow(
AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, UNRESTRICTED_UID,
UNRESTRICTED_PACKAGE_NAME);
doReturn(mPackageManager).when(mContext).getPackageManager(); doReturn(mPackageManager).when(mContext).getPackageManager();
doReturn(mApplicationInfo).when(mPackageManager).getApplicationInfo(eq(PACKAGE_NAME), doReturn(mApplicationInfo).when(mPackageManager).getApplicationInfo(any(),
anyInt()); anyInt());
doReturn(PACKAGE_NAME).when(mApplicationInfo).loadLabel(any()); doReturn(PACKAGE_NAME).when(mApplicationInfo).loadLabel(any());
doThrow(new PackageManager.NameNotFoundException()).when( doThrow(new PackageManager.NameNotFoundException()).when(
@@ -116,6 +121,10 @@ public class RestrictAppDetectorTest {
@Test @Test
public void testDetect_hasAutoHandledAnomaly_tipHandled() { public void testDetect_hasAutoHandledAnomaly_tipHandled() {
mAppInfoList.add(new AppInfo.Builder()
.setUid(RESTRICTED_UID)
.setPackageName(RESTRICTED_PACKAGE_NAME)
.build());
doReturn(new ArrayList<AppInfo>()).when(mBatteryDatabaseManager) doReturn(new ArrayList<AppInfo>()).when(mBatteryDatabaseManager)
.queryAllAnomalies(anyLong(), eq(AnomalyDatabaseHelper.State.NEW)); .queryAllAnomalies(anyLong(), eq(AnomalyDatabaseHelper.State.NEW));
doReturn(mAppInfoList).when(mBatteryDatabaseManager) doReturn(mAppInfoList).when(mBatteryDatabaseManager)
@@ -126,7 +135,7 @@ public class RestrictAppDetectorTest {
} }
@Test @Test
public void testDetect_hasUninstalledAnomaly_removeIt() { public void testDetect_typeNewHasUninstalledAnomaly_removeIt() {
mAppInfoList.add(new AppInfo.Builder() mAppInfoList.add(new AppInfo.Builder()
.setPackageName(UNINSTALLED_PACKAGE_NAME) .setPackageName(UNINSTALLED_PACKAGE_NAME)
.build()); .build());
@@ -139,7 +148,7 @@ public class RestrictAppDetectorTest {
} }
@Test @Test
public void testDetect_hasRestrictedAnomaly_removeIt() throws public void testDetect_typeNewHasRestrictedAnomaly_removeIt() throws
PackageManager.NameNotFoundException { PackageManager.NameNotFoundException {
mAppInfoList.add(new AppInfo.Builder() mAppInfoList.add(new AppInfo.Builder()
.setUid(RESTRICTED_UID) .setUid(RESTRICTED_UID)
@@ -155,6 +164,25 @@ public class RestrictAppDetectorTest {
assertThat(restrictAppTip.getRestrictAppList()).containsExactly(mAppInfo); assertThat(restrictAppTip.getRestrictAppList()).containsExactly(mAppInfo);
} }
@Test
public void testDetect_typeHandledHasUnRestrictedAnomaly_removeIt() throws
PackageManager.NameNotFoundException {
mAppInfoList.clear();
mAppInfoList.add(new AppInfo.Builder()
.setUid(UNRESTRICTED_UID)
.setPackageName(UNRESTRICTED_PACKAGE_NAME)
.build());
doReturn(new ArrayList<>()).when(mBatteryDatabaseManager)
.queryAllAnomalies(anyLong(), eq(AnomalyDatabaseHelper.State.NEW));
doReturn(mAppInfoList).when(mBatteryDatabaseManager)
.queryAllAnomalies(anyLong(), eq(AnomalyDatabaseHelper.State.AUTO_HANDLED));
doReturn(mApplicationInfo).when(mPackageManager).getApplicationInfo(
eq(UNRESTRICTED_PACKAGE_NAME), anyInt());
final RestrictAppTip restrictAppTip = (RestrictAppTip) mRestrictAppDetector.detect();
assertThat(restrictAppTip.getState()).isEqualTo(BatteryTip.StateType.INVISIBLE);
}
@Test @Test
public void testDetect_noAnomaly_tipInvisible() { public void testDetect_noAnomaly_tipInvisible() {
doReturn(new ArrayList<AppInfo>()).when(mBatteryDatabaseManager) doReturn(new ArrayList<AppInfo>()).when(mBatteryDatabaseManager)

View File

@@ -55,7 +55,7 @@ public class RestrictAppTest {
} }
@Test @Test
public void testBatterySettings_hasOneAnomaly_showAnomaly() throws public void batterySettings_hasOneAnomaly_showAnomaly() throws
PackageManager.NameNotFoundException { PackageManager.NameNotFoundException {
mBatteryDatabaseManager.insertAnomaly(mPackageManager.getPackageUid(PACKAGE_SETTINGS, 0), mBatteryDatabaseManager.insertAnomaly(mPackageManager.getPackageUid(PACKAGE_SETTINGS, 0),
PACKAGE_SETTINGS, 1, PACKAGE_SETTINGS, 1,
@@ -67,7 +67,7 @@ public class RestrictAppTest {
} }
@Test @Test
public void testBatterySettings_hasTwoAnomalies_showAnomalies() throws public void batterySettings_hasTwoAnomalies_showAnomalies() throws
PackageManager.NameNotFoundException { PackageManager.NameNotFoundException {
mBatteryDatabaseManager.insertAnomaly(mPackageManager.getPackageUid(PACKAGE_SETTINGS, 0), mBatteryDatabaseManager.insertAnomaly(mPackageManager.getPackageUid(PACKAGE_SETTINGS, 0),
PACKAGE_SETTINGS, 1, PACKAGE_SETTINGS, 1,
@@ -80,4 +80,19 @@ public class RestrictAppTest {
instrumentation.startActivitySync(new Intent(BATTERY_INTENT)); instrumentation.startActivitySync(new Intent(BATTERY_INTENT));
onView(withText("Restrict 2 apps")).check(matches(isDisplayed())); onView(withText("Restrict 2 apps")).check(matches(isDisplayed()));
} }
@Test
public void batterySettings_hasAutoHandledAnomalies_showAutoHandled() throws
PackageManager.NameNotFoundException {
mBatteryDatabaseManager.insertAnomaly(mPackageManager.getPackageUid(PACKAGE_SETTINGS, 0),
PACKAGE_SETTINGS, 1,
AnomalyDatabaseHelper.State.AUTO_HANDLED, System.currentTimeMillis());
mBatteryDatabaseManager.insertAnomaly(mPackageManager.getPackageUid(PACKAGE_SYSTEM_UI, 0),
PACKAGE_SYSTEM_UI, 1,
AnomalyDatabaseHelper.State.AUTO_HANDLED, System.currentTimeMillis());
Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
instrumentation.startActivitySync(new Intent(BATTERY_INTENT));
onView(withText("2 apps recently restricted")).check(matches(isDisplayed()));
}
} }