Revamp the battery detail page for each app

1. Move preferences to new postion
2. Change background activity pref from SwitchPreference to
Preference and update the controller

Bug: 72227981
Test: RunSettingsRoboTests
Change-Id: Ib18ac7523c24d19754c37ab8ac527095d9ced49c
This commit is contained in:
jackqdyulei
2018-01-19 17:32:23 -08:00
parent 35fc0a9a9b
commit 29002aacb0
5 changed files with 77 additions and 86 deletions

View File

@@ -4719,7 +4719,7 @@
<string name="power_charge_remaining"><xliff:g id="until_charged">%1$s</xliff:g> to charge</string>
<!-- Title for the background activity setting, which allows a user to control whether an app can run in the background [CHAR_LIMIT=40] -->
<string name="background_activity_title">Background activity</string>
<string name="background_activity_title">Restricted</string>
<!-- Summary for the background activity [CHAR_LIMIT=120] -->
<string name="background_activity_summary">Allow the app to run in the background</string>
<!-- Summary for the background activity when it is on [CHAR_LIMIT=120] -->
@@ -7602,6 +7602,11 @@
<!-- Button label to say no to the question of whether to require PIN/password/pattern to start your device. [CHAR LIMIT=20] -->
<string name="encryption_interstitial_no">No</string>
<!-- Label to say yes to the question of whether app is restricted. [CHAR LIMIT=20] -->
<string name="restricted_true_label">Yes</string>
<!-- Label to say no to the question of whether app is restricted. [CHAR LIMIT=20] -->
<string name="restricted_false_label">No</string>
<!-- Title for encryption dialog that disables TalkBack. [CHAR_LIMIT=25] -->
<string name="encrypt_talkback_dialog_require_pin">Require PIN?</string>

View File

@@ -27,6 +27,22 @@
android:key="action_buttons"
android:order="-9999"/>
<PreferenceCategory
android:title="@string/battery_detail_manage_title">
<Preference
android:key="background_activity"
android:title="@string/background_activity_title"
android:selectable="true"/>
<Preference
android:key="battery_optimization"
android:title="@string/high_power_apps"
android:summary="@string/high_power_off"
android:selectable="true"/>
</PreferenceCategory>
<Preference
android:key="high_usage"
android:icon="@drawable/ic_battery_alert_24dp"
@@ -52,20 +68,4 @@
</PreferenceCategory>
<PreferenceCategory
android:title="@string/battery_detail_manage_title">
<SwitchPreference
android:key="background_activity"
android:title="@string/background_activity_title"
android:selectable="true"/>
<Preference
android:key="battery_optimization"
android:title="@string/high_power_apps"
android:summary="@string/high_power_off"
android:selectable="true"/>
</PreferenceCategory>
</PreferenceScreen>

View File

@@ -374,7 +374,7 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements
@Override
public void onLimitBackgroundActivity() {
mBackgroundActivityPreferenceController.setUnchecked(
mBackgroundActivityPreferenceController.setRestricted(
findPreference(mBackgroundActivityPreferenceController.getPreferenceKey()));
}
}

View File

@@ -43,12 +43,12 @@ import com.android.settingslib.fuelgauge.PowerWhitelistBackend;
* Controller to control whether an app can run in the background
*/
public class BackgroundActivityPreferenceController extends AbstractPreferenceController
implements PreferenceControllerMixin, Preference.OnPreferenceChangeListener {
implements PreferenceControllerMixin {
private static final String TAG = "BgActivityPrefContr";
private static final String KEY_BACKGROUND_ACTIVITY = "background_activity";
@VisibleForTesting
static final String KEY_BACKGROUND_ACTIVITY = "background_activity";
private final PackageManager mPackageManager;
private final AppOpsManager mAppOpsManager;
private final UserManager mUserManager;
private final int mUid;
@@ -70,7 +70,6 @@ public class BackgroundActivityPreferenceController extends AbstractPreferenceCo
int uid, String packageName, PowerWhitelistBackend backend) {
super(context);
mPowerWhitelistBackend = backend;
mPackageManager = context.getPackageManager();
mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
mDpm = new DevicePolicyManagerWrapper(
(DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE));
@@ -86,11 +85,6 @@ public class BackgroundActivityPreferenceController extends AbstractPreferenceCo
final int mode = mAppOpsManager
.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 = whitelisted || mode != AppOpsManager.MODE_IGNORED;
((SwitchPreference) preference).setChecked(checked);
}
if (whitelisted || mode == AppOpsManager.MODE_ERRORED
|| Utils.isProfileOrDeviceOwner(mUserManager, mDpm, mTargetPackage)) {
preference.setEnabled(false);
@@ -109,9 +103,8 @@ public class BackgroundActivityPreferenceController extends AbstractPreferenceCo
* Called from the warning dialog, if the user decides to go ahead and disable background
* activity for this package
*/
public void setUnchecked(Preference preference) {
public void setRestricted(Preference preference) {
mBatteryUtils.setForceAppStandby(mUid, mTargetPackage, AppOpsManager.MODE_IGNORED);
((SwitchPreference) preference).setChecked(false);
updateSummary(preference);
}
@@ -121,12 +114,13 @@ public class BackgroundActivityPreferenceController extends AbstractPreferenceCo
}
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
final boolean switchOn = (Boolean) newValue;
if (!switchOn) {
final WarningDialogFragment dialogFragment = new WarningDialogFragment();
dialogFragment.setTargetFragment(mFragment, 0);
dialogFragment.show(mFragment.getFragmentManager(), TAG);
public boolean handlePreferenceTreeClick(Preference preference) {
if (KEY_BACKGROUND_ACTIVITY.equals(preference.getKey())) {
final int mode = mAppOpsManager
.checkOpNoThrow(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, mUid, mTargetPackage);
final boolean restricted = mode == AppOpsManager.MODE_IGNORED;
if (!restricted) {
showDialog();
return false;
}
mBatteryUtils.setForceAppStandby(mUid, mTargetPackage, AppOpsManager.MODE_ALLOWED);
@@ -134,6 +128,9 @@ public class BackgroundActivityPreferenceController extends AbstractPreferenceCo
return true;
}
return false;
}
@VisibleForTesting
void updateSummary(Preference preference) {
if (mPowerWhitelistBackend.isWhitelisted(mTargetPackage)) {
@@ -146,12 +143,19 @@ public class BackgroundActivityPreferenceController extends AbstractPreferenceCo
if (mode == AppOpsManager.MODE_ERRORED) {
preference.setSummary(R.string.background_activity_summary_disabled);
} else {
final boolean checked = mode != AppOpsManager.MODE_IGNORED;
preference.setSummary(checked ? R.string.background_activity_summary_on
: R.string.background_activity_summary_off);
final boolean restricted = mode == AppOpsManager.MODE_IGNORED;
preference.setSummary(restricted ? R.string.restricted_true_label
: R.string.restricted_false_label);
}
}
@VisibleForTesting
void showDialog() {
final WarningDialogFragment dialogFragment = new WarningDialogFragment();
dialogFragment.setTargetFragment(mFragment, 0 /* requestCode */);
dialogFragment.show(mFragment.getFragmentManager(), TAG);
}
interface WarningConfirmationListener {
void onLimitBackgroundActivity();
}

View File

@@ -22,6 +22,7 @@ import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
@@ -38,6 +39,7 @@ import android.content.pm.PackageManager;
import android.os.Build;
import android.os.UserManager;
import android.support.v14.preference.SwitchPreference;
import android.support.v7.preference.Preference;
import android.widget.Button;
import com.android.settings.R;
@@ -92,12 +94,12 @@ public class BackgroundActivityPreferenceControllerTest {
private DevicePolicyManager mDevicePolicyManager;
@Mock
private DevicePolicyManagerWrapper mDevicePolicyManagerWrapper;
@Mock
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private AdvancedPowerUsageDetail mFragment;
@Mock
private PowerWhitelistBackend mPowerWhitelistBackend;
private BackgroundActivityPreferenceController mController;
private SwitchPreference mPreference;
private Preference mPreference;
private Context mShadowContext;
private BatteryUtils mBatteryUtils;
@@ -125,7 +127,8 @@ public class BackgroundActivityPreferenceControllerTest {
mBatteryUtils = spy(new BatteryUtils(mShadowContext));
doNothing().when(mBatteryUtils).setForceAppStandby(anyInt(), anyString(), anyInt());
mPreference = new SwitchPreference(mShadowContext);
mPreference = new Preference(mShadowContext);
mPreference.setKey(BackgroundActivityPreferenceController.KEY_BACKGROUND_ACTIVITY);
mController = spy(new BackgroundActivityPreferenceController(
mContext, mFragment, UID_LOW_SDK, LOW_SDK_PACKAGE, mPowerWhitelistBackend));
mController.mDpm = mDevicePolicyManagerWrapper;
@@ -133,49 +136,33 @@ public class BackgroundActivityPreferenceControllerTest {
}
@Test
public void testOnPreferenceChange_TurnOnCheck_MethodInvoked() {
mController.onPreferenceChange(mPreference, true);
public void testHandlePreferenceTreeClick_restrictApp_showDialog() {
doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager).checkOpNoThrow(anyInt(),
anyInt(), anyString());
mController.handlePreferenceTreeClick(mPreference);
verify(mController).showDialog();
}
@Test
public void testHandlePreferenceTreeClick_unRestrictApp_setModeAllowed() {
doReturn(AppOpsManager.MODE_IGNORED).when(mAppOpsManager).checkOpNoThrow(anyInt(),
anyInt(), anyString());
mController.handlePreferenceTreeClick(mPreference);
verify(mBatteryUtils).setForceAppStandby(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_TurnOnCheckHighSDK_MethodInvoked() {
mController = new BackgroundActivityPreferenceController(mContext, mFragment, UID_HIGH_SDK,
HIGH_SDK_PACKAGE, mPowerWhitelistBackend);
mController.mBatteryUtils = mBatteryUtils;
mController.onPreferenceChange(mPreference, true);
verify(mBatteryUtils).setForceAppStandby(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() {
public void testUpdateState_noError_setEnabled() {
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_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);
}
@@ -184,7 +171,6 @@ public class BackgroundActivityPreferenceControllerTest {
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));
@@ -202,27 +188,23 @@ public class BackgroundActivityPreferenceControllerTest {
}
@Test
public void testUpdateSummary_modeDefault_showSummaryOn() {
public void testUpdateSummary_modeDefault_showNotRestricted() {
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);
mController.updateSummary(mPreference);
assertThat(mPreference.getSummary()).isEqualTo(expectedSummary);
assertThat(mPreference.getSummary()).isEqualTo("No");
}
@Test
public void testUpdateSummary_modeIgnored_showSummaryOff() {
public void testUpdateSummary_modeIgnored_showRestricted() {
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);
mController.updateSummary(mPreference);
assertThat(mPreference.getSummary()).isEqualTo(expectedSummary);
assertThat(mPreference.getSummary()).isEqualTo("Yes");
}
@Test