Adding switch for Forced App Standby
Reusing the 'Background activity' switch found in App Info. The switch
now needs to be shown for all apps and will toggle another app op
RUN_ANY_IN_BACKGROUND which controls whether jobs or alarms are run for
background apps.
Also fixed handling of multiple packages with shared uid. The controller
was picking the first package for uid but the order of packages can
change on a reboot which would cause wrong app ops settings across
packages of the same uid.
Test: make -j32 RunSettingsRoboTests
Bug: 65176793
Change-Id: I2a9b96bc02730776172c3ae317cb7f7f890bec30
diff --git a/res/values/strings.xml b/res/values/strings.xml
index fcc0b6d..c58f6bb 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -4630,6 +4630,12 @@
<string name="background_activity_summary_off">App\'s background activity is limited when not in use</string>
<!-- Summary for the background activity when it is disabled [CHAR_LIMIT=120] -->
<string name="background_activity_summary_disabled">App not allowed to run in background</string>
+ <!-- TODO: Pending UX review. Summary for the background activity when it is whitlisted [CHAR_LIMIT=120] -->
+ <string name="background_activity_summary_whitelisted">App can not be optimized for battery use</string>
+ <!-- TODO: Pending UX review. Title for the warning dialog to show to the user when limiting background activity for an app -->
+ <string name="background_activity_warning_dialog_title">Limit background activity?</string>
+ <!-- TODO: Pending UX review. Text for the warning dialog to show to the user when limiting background activity for an app -->
+ <string name="background_activity_warning_dialog_text">If you limit background activity for an app, it may misbehave</string>
<!-- Title for the screen usage in power use UI [CHAR_LIMIT=60] -->
<string name="device_screen_usage">Screen usage since full charge</string>
diff --git a/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java b/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java
index 0142e62..66a0ca2 100644
--- a/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java
+++ b/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java
@@ -68,7 +68,8 @@
public class AdvancedPowerUsageDetail extends DashboardFragment implements
ButtonActionDialogFragment.AppButtonsDialogListener,
AnomalyDialogFragment.AnomalyDialogListener,
- LoaderManager.LoaderCallbacks<List<Anomaly>> {
+ LoaderManager.LoaderCallbacks<List<Anomaly>>,
+ BackgroundActivityPreferenceController.WarningConfirmationListener {
public static final String TAG = "AdvancedPowerUsageDetail";
public static final String EXTRA_UID = "extra_uid";
@@ -109,6 +110,7 @@
@VisibleForTesting
AnomalySummaryPreferenceController mAnomalySummaryPreferenceController;
private AppButtonsPreferenceController mAppButtonsPreferenceController;
+ private BackgroundActivityPreferenceController mBackgroundActivityPreferenceController;
private DevicePolicyManagerWrapper mDpm;
private UserManager mUserManager;
@@ -319,7 +321,9 @@
final int uid = bundle.getInt(EXTRA_UID, 0);
final String packageName = bundle.getString(EXTRA_PACKAGE_NAME);
- controllers.add(new BackgroundActivityPreferenceController(context, uid));
+ mBackgroundActivityPreferenceController = new BackgroundActivityPreferenceController(
+ context, this, uid, packageName);
+ controllers.add(mBackgroundActivityPreferenceController);
controllers.add(new BatteryOptimizationPreferenceController(
(SettingsActivity) getActivity(), this, packageName));
mAppButtonsPreferenceController = new AppButtonsPreferenceController(
@@ -364,4 +368,10 @@
public void onLoaderReset(Loader<List<Anomaly>> loader) {
}
+
+ @Override
+ public void onLimitBackgroundActivity() {
+ mBackgroundActivityPreferenceController.setUnchecked(
+ findPreference(mBackgroundActivityPreferenceController.getPreferenceKey()));
+ }
}
diff --git a/src/com/android/settings/fuelgauge/BackgroundActivityPreferenceController.java b/src/com/android/settings/fuelgauge/BackgroundActivityPreferenceController.java
index 4d1cf77..cea6d16 100644
--- a/src/com/android/settings/fuelgauge/BackgroundActivityPreferenceController.java
+++ b/src/com/android/settings/fuelgauge/BackgroundActivityPreferenceController.java
@@ -14,12 +14,17 @@
package com.android.settings.fuelgauge;
+import android.app.AlertDialog;
import android.app.AppOpsManager;
+import android.app.Dialog;
+import android.app.Fragment;
import android.app.admin.DevicePolicyManager;
import android.content.Context;
+import android.content.DialogInterface;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.Build;
+import android.os.Bundle;
import android.os.UserManager;
import android.support.annotation.VisibleForTesting;
import android.support.v14.preference.SwitchPreference;
@@ -29,6 +34,7 @@
import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
import com.android.settings.enterprise.DevicePolicyManagerWrapper;
import com.android.settings.enterprise.DevicePolicyManagerWrapperImpl;
import com.android.settingslib.core.AbstractPreferenceController;
@@ -45,54 +51,72 @@
private final PackageManager mPackageManager;
private final AppOpsManager mAppOpsManager;
private final UserManager mUserManager;
- private final String[] mPackages;
private final int mUid;
@VisibleForTesting
DevicePolicyManagerWrapper mDpm;
-
+ private Fragment mFragment;
private String mTargetPackage;
+ private boolean mIsPreOApp;
+ private PowerWhitelistBackend mPowerWhitelistBackend;
- public BackgroundActivityPreferenceController(Context context, int uid) {
+ public BackgroundActivityPreferenceController(Context context, Fragment fragment,
+ int uid, String packageName) {
+ this(context, fragment, uid, packageName, PowerWhitelistBackend.getInstance());
+ }
+
+ @VisibleForTesting
+ BackgroundActivityPreferenceController(Context context, Fragment fragment,
+ int uid, String packageName, PowerWhitelistBackend backend) {
super(context);
+ mPowerWhitelistBackend = backend;
mPackageManager = context.getPackageManager();
mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
mDpm = new DevicePolicyManagerWrapperImpl(
(DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE));
mAppOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
mUid = uid;
- mPackages = mPackageManager.getPackagesForUid(mUid);
+ mFragment = fragment;
+ mTargetPackage = packageName;
+ mIsPreOApp = isLegacyApp(packageName);
}
@Override
public void updateState(Preference preference) {
final int mode = mAppOpsManager
- .checkOpNoThrow(AppOpsManager.OP_RUN_IN_BACKGROUND, mUid, mTargetPackage);
+ .checkOpNoThrow(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, mUid, mTargetPackage);
+ final boolean whitelisted = mPowerWhitelistBackend.isWhitelisted(mTargetPackage);
// Set checked or not before we may set it disabled
if (mode != AppOpsManager.MODE_ERRORED) {
- final boolean checked = mode != AppOpsManager.MODE_IGNORED;
+ final boolean checked = whitelisted || mode != AppOpsManager.MODE_IGNORED;
((SwitchPreference) preference).setChecked(checked);
}
- if (mode == AppOpsManager.MODE_ERRORED
+ if (whitelisted || mode == AppOpsManager.MODE_ERRORED
|| Utils.isProfileOrDeviceOwner(mUserManager, mDpm, mTargetPackage)) {
preference.setEnabled(false);
+ } else {
+ preference.setEnabled(true);
}
-
updateSummary(preference);
}
@Override
public boolean isAvailable() {
- if (mPackages == null) {
- return false;
- }
- for (final String packageName : mPackages) {
- if (isLegacyApp(packageName)) {
- mTargetPackage = packageName;
- return true;
- }
- }
+ return mTargetPackage != null;
+ }
- return false;
+ /**
+ * Called from the warning dialog, if the user decides to go ahead and disable background
+ * activity for this package
+ */
+ public void setUnchecked(Preference preference) {
+ if (mIsPreOApp) {
+ mAppOpsManager.setMode(AppOpsManager.OP_RUN_IN_BACKGROUND, mUid, mTargetPackage,
+ AppOpsManager.MODE_IGNORED);
+ }
+ mAppOpsManager.setMode(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, mUid, mTargetPackage,
+ AppOpsManager.MODE_IGNORED);
+ ((SwitchPreference) preference).setChecked(false);
+ updateSummary(preference);
}
@Override
@@ -102,20 +126,24 @@
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
- boolean switchOn = (Boolean) newValue;
- mAppOpsManager.setMode(AppOpsManager.OP_RUN_IN_BACKGROUND, mUid, mTargetPackage,
- switchOn ? AppOpsManager.MODE_ALLOWED : AppOpsManager.MODE_IGNORED);
-
+ final boolean switchOn = (Boolean) newValue;
+ if (!switchOn) {
+ final WarningDialogFragment dialogFragment = new WarningDialogFragment();
+ dialogFragment.setTargetFragment(mFragment, 0);
+ dialogFragment.show(mFragment.getFragmentManager(), TAG);
+ return false;
+ }
+ if (mIsPreOApp) {
+ mAppOpsManager.setMode(AppOpsManager.OP_RUN_IN_BACKGROUND, mUid, mTargetPackage,
+ AppOpsManager.MODE_ALLOWED);
+ }
+ mAppOpsManager.setMode(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, mUid, mTargetPackage,
+ AppOpsManager.MODE_ALLOWED);
updateSummary(preference);
return true;
}
@VisibleForTesting
- String getTargetPackage() {
- return mTargetPackage;
- }
-
- @VisibleForTesting
boolean isLegacyApp(final String packageName) {
try {
ApplicationInfo info = mPackageManager.getApplicationInfo(packageName,
@@ -131,8 +159,12 @@
@VisibleForTesting
void updateSummary(Preference preference) {
+ if (mPowerWhitelistBackend.isWhitelisted(mTargetPackage)) {
+ preference.setSummary(R.string.background_activity_summary_whitelisted);
+ return;
+ }
final int mode = mAppOpsManager
- .checkOpNoThrow(AppOpsManager.OP_RUN_IN_BACKGROUND, mUid, mTargetPackage);
+ .checkOpNoThrow(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, mUid, mTargetPackage);
if (mode == AppOpsManager.MODE_ERRORED) {
preference.setSummary(R.string.background_activity_summary_disabled);
@@ -142,4 +174,37 @@
: R.string.background_activity_summary_off);
}
}
+
+ interface WarningConfirmationListener {
+ void onLimitBackgroundActivity();
+ }
+
+ /**
+ * Warning dialog to show to the user as turning off background activity can lead to
+ * apps misbehaving as their background task scheduling guarantees will no longer be honored.
+ */
+ public static class WarningDialogFragment extends InstrumentedDialogFragment {
+ @Override
+ public int getMetricsCategory() {
+ // TODO (b/65494831): add metric id
+ return 0;
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ final WarningConfirmationListener listener =
+ (WarningConfirmationListener) getTargetFragment();
+ return new AlertDialog.Builder(getContext())
+ .setTitle(R.string.background_activity_warning_dialog_title)
+ .setMessage(R.string.background_activity_warning_dialog_text)
+ .setPositiveButton(R.string.dlg_ok, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ listener.onLimitBackgroundActivity();
+ }
+ })
+ .setNegativeButton(R.string.dlg_cancel, null)
+ .create();
+ }
+ }
}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BackgroundActivityPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BackgroundActivityPreferenceControllerTest.java
index 91f4a2b..86836f9 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/BackgroundActivityPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BackgroundActivityPreferenceControllerTest.java
@@ -16,14 +16,25 @@
package com.android.settings.fuelgauge;
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.robolectric.Shadows.shadowOf;
+
+import android.app.AlertDialog;
import android.app.AppOpsManager;
import android.app.admin.DevicePolicyManager;
import android.content.Context;
+import android.content.DialogInterface;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.UserManager;
import android.support.v14.preference.SwitchPreference;
+import android.widget.Button;
import com.android.settings.R;
import com.android.settings.TestConfig;
@@ -38,22 +49,17 @@
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
+import org.robolectric.shadows.ShadowAlertDialog;
+import org.robolectric.shadows.ShadowDialog;
+import org.robolectric.util.FragmentTestUtil;
@RunWith(RobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class BackgroundActivityPreferenceControllerTest {
- private static final int UID_NORMAL = 1234;
- private static final int UID_SPECIAL = 2345;
+ private static final int UID_LOW_SDK = 1234;
+ private static final int UID_HIGH_SDK = 3456;
private static final String HIGH_SDK_PACKAGE = "com.android.package.high";
private static final String LOW_SDK_PACKAGE = "com.android.package.low";
- private static final String[] PACKAGES_NORMAL = {LOW_SDK_PACKAGE};
- private static final String[] PACKAGES_SPECIAL = {HIGH_SDK_PACKAGE, LOW_SDK_PACKAGE};
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private Context mContext;
@@ -71,6 +77,10 @@
private DevicePolicyManager mDevicePolicyManager;
@Mock
private DevicePolicyManagerWrapper mDevicePolicyManagerWrapper;
+ @Mock
+ private AdvancedPowerUsageDetail mFragment;
+ @Mock
+ private PowerWhitelistBackend mPowerWhitelistBackend;
private BackgroundActivityPreferenceController mController;
private SwitchPreference mPreference;
private Context mShadowContext;
@@ -85,19 +95,19 @@
when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
when(mContext.getSystemService(Context.DEVICE_POLICY_SERVICE)).thenReturn(
mDevicePolicyManager);
- when(mPackageManager.getPackagesForUid(UID_NORMAL)).thenReturn(PACKAGES_NORMAL);
- when(mPackageManager.getPackagesForUid(UID_SPECIAL)).thenReturn(PACKAGES_SPECIAL);
when(mPackageManager.getApplicationInfo(HIGH_SDK_PACKAGE, PackageManager.GET_META_DATA))
.thenReturn(mHighApplicationInfo);
when(mPackageManager.getApplicationInfo(LOW_SDK_PACKAGE, PackageManager.GET_META_DATA))
.thenReturn(mLowApplicationInfo);
+
+ when(mPowerWhitelistBackend.isWhitelisted(LOW_SDK_PACKAGE)).thenReturn(false);
mHighApplicationInfo.targetSdkVersion = Build.VERSION_CODES.O;
mLowApplicationInfo.targetSdkVersion = Build.VERSION_CODES.L;
mPreference = new SwitchPreference(mShadowContext);
- mController = spy(new BackgroundActivityPreferenceController(mContext, UID_NORMAL));
- mController.isAvailable();
+ mController = spy(new BackgroundActivityPreferenceController(
+ mContext, mFragment, UID_LOW_SDK, LOW_SDK_PACKAGE, mPowerWhitelistBackend));
mController.mDpm = mDevicePolicyManagerWrapper;
}
@@ -105,49 +115,66 @@
public void testOnPreferenceChange_TurnOnCheck_MethodInvoked() {
mController.onPreferenceChange(mPreference, true);
- verify(mAppOpsManager).setMode(AppOpsManager.OP_RUN_IN_BACKGROUND, UID_NORMAL,
- mController.getTargetPackage(), AppOpsManager.MODE_ALLOWED);
- verify(mController).updateSummary(mPreference);
+ verify(mAppOpsManager).setMode(AppOpsManager.OP_RUN_IN_BACKGROUND, UID_LOW_SDK,
+ LOW_SDK_PACKAGE, AppOpsManager.MODE_ALLOWED);
+ verify(mAppOpsManager).setMode(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, UID_LOW_SDK,
+ LOW_SDK_PACKAGE, AppOpsManager.MODE_ALLOWED);
+
+ assertThat(mPreference.getSummary())
+ .isEqualTo(mShadowContext.getText(R.string.background_activity_summary_on));
}
@Test
- public void testOnPreferenceChange_TurnOffCheck_MethodInvoked() {
- mController.onPreferenceChange(mPreference, false);
-
- verify(mAppOpsManager).setMode(AppOpsManager.OP_RUN_IN_BACKGROUND, UID_NORMAL,
- mController.getTargetPackage(), AppOpsManager.MODE_IGNORED);
- verify(mController).updateSummary(mPreference);
+ public void testOnPreferenceChange_TurnOnCheckHighSDK_MethodInvoked() {
+ mController = new BackgroundActivityPreferenceController(mContext, mFragment, UID_HIGH_SDK,
+ HIGH_SDK_PACKAGE, mPowerWhitelistBackend);
+ mController.onPreferenceChange(mPreference, true);
+ verify(mAppOpsManager).setMode(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, UID_HIGH_SDK,
+ HIGH_SDK_PACKAGE, AppOpsManager.MODE_ALLOWED);
+ verify(mAppOpsManager, never()).setMode(AppOpsManager.OP_RUN_IN_BACKGROUND, UID_HIGH_SDK,
+ HIGH_SDK_PACKAGE, AppOpsManager.MODE_ALLOWED);
+ assertThat(mPreference.getSummary())
+ .isEqualTo(mShadowContext.getText(R.string.background_activity_summary_on));
}
@Test
public void testUpdateState_CheckOn_SetCheckedTrue() {
- when(mAppOpsManager
- .checkOpNoThrow(AppOpsManager.OP_RUN_IN_BACKGROUND, UID_NORMAL, LOW_SDK_PACKAGE))
- .thenReturn(AppOpsManager.MODE_DEFAULT);
+ when(mAppOpsManager.checkOpNoThrow(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, UID_LOW_SDK,
+ LOW_SDK_PACKAGE)).thenReturn(AppOpsManager.MODE_ALLOWED);
mController.updateState(mPreference);
assertThat(mPreference.isChecked()).isTrue();
+ assertThat(mPreference.isEnabled()).isTrue();
verify(mController).updateSummary(mPreference);
}
@Test
public void testUpdateState_CheckOff_SetCheckedFalse() {
- when(mAppOpsManager
- .checkOpNoThrow(AppOpsManager.OP_RUN_IN_BACKGROUND, UID_NORMAL, LOW_SDK_PACKAGE))
- .thenReturn(AppOpsManager.MODE_IGNORED);
+ when(mAppOpsManager.checkOpNoThrow(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, UID_LOW_SDK,
+ LOW_SDK_PACKAGE)).thenReturn(AppOpsManager.MODE_IGNORED);
mController.updateState(mPreference);
assertThat(mPreference.isChecked()).isFalse();
+ assertThat(mPreference.isEnabled()).isTrue();
verify(mController).updateSummary(mPreference);
}
@Test
+ public void testUpdateState_whitelisted() {
+ when(mPowerWhitelistBackend.isWhitelisted(LOW_SDK_PACKAGE)).thenReturn(true);
+ mController.updateState(mPreference);
+ assertThat(mPreference.isChecked()).isTrue();
+ assertThat(mPreference.isEnabled()).isFalse();
+ assertThat(mPreference.getSummary()).isEqualTo(
+ mShadowContext.getText(R.string.background_activity_summary_whitelisted));
+ }
+
+ @Test
public void testUpdateSummary_modeError_showSummaryDisabled() {
- when(mAppOpsManager
- .checkOpNoThrow(AppOpsManager.OP_RUN_IN_BACKGROUND, UID_NORMAL, LOW_SDK_PACKAGE))
- .thenReturn(AppOpsManager.MODE_ERRORED);
+ when(mAppOpsManager.checkOpNoThrow(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, UID_LOW_SDK,
+ LOW_SDK_PACKAGE)).thenReturn(AppOpsManager.MODE_ERRORED);
final CharSequence expectedSummary = mShadowContext.getText(
R.string.background_activity_summary_disabled);
mController.updateSummary(mPreference);
@@ -157,9 +184,8 @@
@Test
public void testUpdateSummary_modeDefault_showSummaryOn() {
- when(mAppOpsManager
- .checkOpNoThrow(AppOpsManager.OP_RUN_IN_BACKGROUND, UID_NORMAL, LOW_SDK_PACKAGE))
- .thenReturn(AppOpsManager.MODE_DEFAULT);
+ when(mAppOpsManager.checkOpNoThrow(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, UID_LOW_SDK,
+ LOW_SDK_PACKAGE)).thenReturn(AppOpsManager.MODE_DEFAULT);
final CharSequence expectedSummary = mShadowContext.getText(
R.string.background_activity_summary_on);
@@ -170,9 +196,8 @@
@Test
public void testUpdateSummary_modeIgnored_showSummaryOff() {
- when(mAppOpsManager
- .checkOpNoThrow(AppOpsManager.OP_RUN_IN_BACKGROUND, UID_NORMAL, LOW_SDK_PACKAGE))
- .thenReturn(AppOpsManager.MODE_IGNORED);
+ when(mAppOpsManager.checkOpNoThrow(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, UID_LOW_SDK,
+ LOW_SDK_PACKAGE)).thenReturn(AppOpsManager.MODE_IGNORED);
final CharSequence expectedSummary = mShadowContext.getText(
R.string.background_activity_summary_off);
@@ -182,31 +207,30 @@
}
@Test
- public void testIsPackageAvailable_SdkLowerThanO_ReturnTrue() {
+ public void testIsLegacyApp_SdkLowerThanO_ReturnTrue() {
assertThat(mController.isLegacyApp(LOW_SDK_PACKAGE)).isTrue();
}
@Test
- public void testIsPackageAvailable_SdkLargerOrEqualThanO_ReturnFalse() {
+ public void testIsLegacyApp_SdkLargerOrEqualThanO_ReturnFalse() {
assertThat(mController.isLegacyApp(HIGH_SDK_PACKAGE)).isFalse();
}
@Test
- public void testMultiplePackages_ReturnStatusForTargetPackage() {
- mController = new BackgroundActivityPreferenceController(mContext, UID_SPECIAL);
- mController.mDpm = mDevicePolicyManagerWrapper;
- when(mAppOpsManager
- .checkOpNoThrow(AppOpsManager.OP_RUN_IN_BACKGROUND, UID_SPECIAL, LOW_SDK_PACKAGE))
- .thenReturn(AppOpsManager.MODE_ALLOWED);
- when(mAppOpsManager
- .checkOpNoThrow(AppOpsManager.OP_RUN_IN_BACKGROUND, UID_SPECIAL, HIGH_SDK_PACKAGE))
- .thenReturn(AppOpsManager.MODE_IGNORED);
+ public void testIsAvailable_ReturnTrue() {
+ assertThat(mController.isAvailable()).isTrue();
+ }
- final boolean available = mController.isAvailable();
- mController.updateState(mPreference);
-
- assertThat(available).isTrue();
- // Should get status from LOW_SDK_PACKAGE
- assertThat(mPreference.isChecked()).isTrue();
+ @Test
+ public void testWarningDialog() {
+ BackgroundActivityPreferenceController.WarningDialogFragment dialogFragment =
+ new BackgroundActivityPreferenceController.WarningDialogFragment();
+ dialogFragment.setTargetFragment(mFragment, 0);
+ FragmentTestUtil.startFragment(dialogFragment);
+ final AlertDialog dialog = (AlertDialog) ShadowDialog.getLatestDialog();
+ ShadowAlertDialog shadowDialog = shadowOf(dialog);
+ final Button okButton = dialog.getButton(DialogInterface.BUTTON_POSITIVE);
+ shadowDialog.clickOn(okButton.getId());
+ verify(mFragment).onLimitBackgroundActivity();
}
}