Fix bugs in auto restriction.
1. Dismiss this tip once user clicks it and goes to detail page. 2. In auto restriction, since apps are automatically restricted, we need to remove apps in list that unrestricted by user. 3. Refactor the code to remove the unnecessary parameter(i.e. SettingsActivity) Bug: 78187414 Test: RunSettingsRoboTests Change-Id: I1c950f7c55df35795641c2ea8579ce9e011dba28
This commit is contained in:
@@ -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;
|
||||||
}
|
}
|
||||||
|
@@ -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)
|
||||||
|
@@ -71,7 +71,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));
|
||||||
}
|
}
|
||||||
|
@@ -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()) {
|
||||||
|
@@ -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);
|
||||||
}
|
}
|
||||||
|
@@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -20,18 +20,17 @@ import android.content.Context;
|
|||||||
import android.support.annotation.VisibleForTesting;
|
import android.support.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);
|
||||||
}
|
}
|
||||||
|
@@ -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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
@@ -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))
|
||||||
|
@@ -67,8 +67,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;
|
||||||
@@ -88,6 +86,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<>();
|
||||||
@@ -119,9 +118,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(
|
||||||
|
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
@@ -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)
|
||||||
|
@@ -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()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user