From bd775d9f62194c80528e43965a4914b4ebb83085 Mon Sep 17 00:00:00 2001 From: Beverly Date: Thu, 14 Dec 2017 09:37:01 -0500 Subject: [PATCH 1/6] ZenModeBackend gets newest notification policy Previously, notification policy wouldn't be updated so behavior zen mode settings pages wouldn't update when an app changed the notification policy. Now notification policy will be updated on updateState of each AbstractZenModePreferenceController. Bug: 70662324 Test: make RunSettingsRoboTests -j40 Change-Id: Ibee20e4f27e0c833e05230ea8a3ea2cc75ae6bf0 --- .../AbstractZenModePreferenceController.java | 16 ++++++++++++---- .../ZenModeAlarmsPreferenceController.java | 2 -- .../settings/notification/ZenModeBackend.java | 1 - .../ZenModeButtonPreferenceController.java | 2 -- .../ZenModeCallsPreferenceController.java | 2 -- .../ZenModeEventsPreferenceController.java | 2 -- .../ZenModeMessagesPreferenceController.java | 2 -- .../ZenModeRemindersPreferenceController.java | 2 -- ...ZenModeRepeatCallersPreferenceController.java | 2 -- .../ZenModeScreenOffPreferenceController.java | 2 -- .../ZenModeScreenOnPreferenceController.java | 2 -- 11 files changed, 12 insertions(+), 23 deletions(-) diff --git a/src/com/android/settings/notification/AbstractZenModePreferenceController.java b/src/com/android/settings/notification/AbstractZenModePreferenceController.java index 33c027cd789..81ceca19c77 100644 --- a/src/com/android/settings/notification/AbstractZenModePreferenceController.java +++ b/src/com/android/settings/notification/AbstractZenModePreferenceController.java @@ -31,7 +31,6 @@ import android.service.notification.ScheduleCalendar; import android.service.notification.ZenModeConfig; import android.support.v7.preference.Preference; import android.support.v7.preference.PreferenceScreen; -import android.util.Slog; import com.android.internal.annotations.VisibleForTesting; import com.android.settings.core.PreferenceControllerMixin; @@ -54,6 +53,7 @@ abstract public class AbstractZenModePreferenceController extends final private NotificationManager mNotificationManager; protected static ZenModeConfigWrapper mZenModeConfigWrapper; protected MetricsFeatureProvider mMetricsFeatureProvider; + protected final ZenModeBackend mBackend; public AbstractZenModePreferenceController(Context context, String key, Lifecycle lifecycle) { @@ -68,6 +68,7 @@ abstract public class AbstractZenModePreferenceController extends final FeatureFactory featureFactory = FeatureFactory.getFactory(mContext); mMetricsFeatureProvider = featureFactory.getMetricsFeatureProvider(); + mBackend = ZenModeBackend.getInstance(context); } @Override @@ -90,6 +91,14 @@ abstract public class AbstractZenModePreferenceController extends } } + @Override + public void updateState(Preference preference) { + super.updateState(preference); + + mBackend.updatePolicy(); + mBackend.updateZenMode(); + } + protected NotificationManager.Policy getPolicy() { return mNotificationManager.getNotificationPolicy(); } @@ -99,8 +108,8 @@ abstract public class AbstractZenModePreferenceController extends } protected int getZenMode() { - return Settings.Global.getInt(mContext.getContentResolver(), - Settings.Global.ZEN_MODE, 0); + return Settings.Global.getInt(mContext.getContentResolver(), Settings.Global.ZEN_MODE, + mBackend.mZenMode); } class SettingObserver extends ContentObserver { @@ -188,7 +197,6 @@ abstract public class AbstractZenModePreferenceController extends } } - return endTimeMs; } diff --git a/src/com/android/settings/notification/ZenModeAlarmsPreferenceController.java b/src/com/android/settings/notification/ZenModeAlarmsPreferenceController.java index a15f7fca550..af5910760e3 100644 --- a/src/com/android/settings/notification/ZenModeAlarmsPreferenceController.java +++ b/src/com/android/settings/notification/ZenModeAlarmsPreferenceController.java @@ -30,11 +30,9 @@ public class ZenModeAlarmsPreferenceController extends AbstractZenModePreferenceController implements Preference.OnPreferenceChangeListener { protected static final String KEY = "zen_mode_alarms"; - private final ZenModeBackend mBackend; public ZenModeAlarmsPreferenceController(Context context, Lifecycle lifecycle) { super(context, KEY, lifecycle); - mBackend = ZenModeBackend.getInstance(context); } @Override diff --git a/src/com/android/settings/notification/ZenModeBackend.java b/src/com/android/settings/notification/ZenModeBackend.java index 945da0b9ca7..6cee28e26aa 100644 --- a/src/com/android/settings/notification/ZenModeBackend.java +++ b/src/com/android/settings/notification/ZenModeBackend.java @@ -82,7 +82,6 @@ public class ZenModeBackend { mZenMode = zenMode; } - /** gets last zen mode set by setZenMode or updateZenMode **/ protected int getZenMode() { mZenMode = Settings.Global.getInt(mContext.getContentResolver(), Settings.Global.ZEN_MODE, mZenMode); diff --git a/src/com/android/settings/notification/ZenModeButtonPreferenceController.java b/src/com/android/settings/notification/ZenModeButtonPreferenceController.java index 1886dab1524..f5169f04500 100644 --- a/src/com/android/settings/notification/ZenModeButtonPreferenceController.java +++ b/src/com/android/settings/notification/ZenModeButtonPreferenceController.java @@ -34,11 +34,9 @@ public class ZenModeButtonPreferenceController extends AbstractZenModePreference protected static final String KEY = "zen_mode_settings_button_container"; private Button mZenButtonOn; private Button mZenButtonOff; - private ZenModeBackend mBackend; public ZenModeButtonPreferenceController(Context context, Lifecycle lifecycle) { super(context, KEY, lifecycle); - mBackend = ZenModeBackend.getInstance(context); } @Override diff --git a/src/com/android/settings/notification/ZenModeCallsPreferenceController.java b/src/com/android/settings/notification/ZenModeCallsPreferenceController.java index d952c11c149..3e2f8022f58 100644 --- a/src/com/android/settings/notification/ZenModeCallsPreferenceController.java +++ b/src/com/android/settings/notification/ZenModeCallsPreferenceController.java @@ -26,11 +26,9 @@ import com.android.settingslib.core.lifecycle.Lifecycle; public class ZenModeCallsPreferenceController extends AbstractZenModePreferenceController { protected static final String KEY = "zen_mode_calls"; - private final ZenModeBackend mBackend; public ZenModeCallsPreferenceController(Context context, Lifecycle lifecycle) { super(context, KEY, lifecycle); - mBackend = ZenModeBackend.getInstance(context); } @Override diff --git a/src/com/android/settings/notification/ZenModeEventsPreferenceController.java b/src/com/android/settings/notification/ZenModeEventsPreferenceController.java index be5e6d6e925..44234949a15 100644 --- a/src/com/android/settings/notification/ZenModeEventsPreferenceController.java +++ b/src/com/android/settings/notification/ZenModeEventsPreferenceController.java @@ -31,11 +31,9 @@ public class ZenModeEventsPreferenceController extends AbstractZenModePreference implements Preference.OnPreferenceChangeListener { protected static final String KEY = "zen_mode_events"; - private final ZenModeBackend mBackend; public ZenModeEventsPreferenceController(Context context, Lifecycle lifecycle) { super(context, KEY, lifecycle); - mBackend = ZenModeBackend.getInstance(context); } @Override diff --git a/src/com/android/settings/notification/ZenModeMessagesPreferenceController.java b/src/com/android/settings/notification/ZenModeMessagesPreferenceController.java index dad6cf13e5c..0ffc44d4b7f 100644 --- a/src/com/android/settings/notification/ZenModeMessagesPreferenceController.java +++ b/src/com/android/settings/notification/ZenModeMessagesPreferenceController.java @@ -10,11 +10,9 @@ import com.android.settingslib.core.lifecycle.Lifecycle; public class ZenModeMessagesPreferenceController extends AbstractZenModePreferenceController { protected static final String KEY = "zen_mode_messages"; - private final ZenModeBackend mBackend; public ZenModeMessagesPreferenceController(Context context, Lifecycle lifecycle) { super(context, KEY, lifecycle); - mBackend = ZenModeBackend.getInstance(context); } @Override diff --git a/src/com/android/settings/notification/ZenModeRemindersPreferenceController.java b/src/com/android/settings/notification/ZenModeRemindersPreferenceController.java index 99a4f0d7b64..b6c29223584 100644 --- a/src/com/android/settings/notification/ZenModeRemindersPreferenceController.java +++ b/src/com/android/settings/notification/ZenModeRemindersPreferenceController.java @@ -30,11 +30,9 @@ public class ZenModeRemindersPreferenceController extends AbstractZenModePrefere implements Preference.OnPreferenceChangeListener { protected static final String KEY = "zen_mode_reminders"; - private final ZenModeBackend mBackend; public ZenModeRemindersPreferenceController(Context context, Lifecycle lifecycle) { super(context, KEY, lifecycle); - mBackend = ZenModeBackend.getInstance(context); } @Override diff --git a/src/com/android/settings/notification/ZenModeRepeatCallersPreferenceController.java b/src/com/android/settings/notification/ZenModeRepeatCallersPreferenceController.java index 82fe865885c..d5c0a007119 100644 --- a/src/com/android/settings/notification/ZenModeRepeatCallersPreferenceController.java +++ b/src/com/android/settings/notification/ZenModeRepeatCallersPreferenceController.java @@ -30,11 +30,9 @@ public class ZenModeRepeatCallersPreferenceController extends AbstractZenModePre implements Preference.OnPreferenceChangeListener { protected static final String KEY = "zen_mode_repeat_callers"; - private final ZenModeBackend mBackend; public ZenModeRepeatCallersPreferenceController(Context context, Lifecycle lifecycle) { super(context, KEY, lifecycle); - mBackend = ZenModeBackend.getInstance(context); } @Override diff --git a/src/com/android/settings/notification/ZenModeScreenOffPreferenceController.java b/src/com/android/settings/notification/ZenModeScreenOffPreferenceController.java index 0ba24c07a9c..81c9b0d3f72 100644 --- a/src/com/android/settings/notification/ZenModeScreenOffPreferenceController.java +++ b/src/com/android/settings/notification/ZenModeScreenOffPreferenceController.java @@ -29,11 +29,9 @@ public class ZenModeScreenOffPreferenceController extends AbstractZenModePreferenceController implements Preference.OnPreferenceChangeListener { protected static final String KEY = "zen_mode_screen_off"; - private final ZenModeBackend mBackend; public ZenModeScreenOffPreferenceController(Context context, Lifecycle lifecycle) { super(context, KEY, lifecycle); - mBackend = ZenModeBackend.getInstance(context); } @Override diff --git a/src/com/android/settings/notification/ZenModeScreenOnPreferenceController.java b/src/com/android/settings/notification/ZenModeScreenOnPreferenceController.java index bcb1af89a0b..bab4dd1abce 100644 --- a/src/com/android/settings/notification/ZenModeScreenOnPreferenceController.java +++ b/src/com/android/settings/notification/ZenModeScreenOnPreferenceController.java @@ -29,11 +29,9 @@ public class ZenModeScreenOnPreferenceController extends AbstractZenModePreferenceController implements Preference.OnPreferenceChangeListener { protected static final String KEY = "zen_mode_screen_on"; - private final ZenModeBackend mBackend; public ZenModeScreenOnPreferenceController(Context context, Lifecycle lifecycle) { super(context, KEY, lifecycle); - mBackend = ZenModeBackend.getInstance(context); } @Override From d94033624a7d4767418dd6f469064d2f9e4c90a5 Mon Sep 17 00:00:00 2001 From: Jeff Sharkey Date: Fri, 5 Jan 2018 17:14:37 -0700 Subject: [PATCH 2/6] Add reserved disk GID to critical component. We recently created a new GID that can be granted to critical system processes, so that the system is usable enough for the user to free up disk space used by abusive apps. Test: builds, boots Bug: 62024591 Change-Id: I4aff50c26878fceace5692252cac66e56a3aea6d --- AndroidManifest.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/AndroidManifest.xml b/AndroidManifest.xml index facfeab50c9..735157c9b4d 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -90,6 +90,7 @@ + Date: Wed, 29 Nov 2017 18:01:25 -0800 Subject: [PATCH 3/6] Rename setDataEnabled to setUserDataEnabled. Test: unittest Bug: 69814555 Change-Id: I1d43dc1d2f720383a2f0be18560fc0fd4ff349fd Merged-In: I1d43dc1d2f720383a2f0be18560fc0fd4ff349fd --- src/com/android/settings/RadioInfo.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/com/android/settings/RadioInfo.java b/src/com/android/settings/RadioInfo.java index 776e3b25bc6..b885483b7fc 100644 --- a/src/com/android/settings/RadioInfo.java +++ b/src/com/android/settings/RadioInfo.java @@ -1142,11 +1142,11 @@ public class RadioInfo extends Activity { switch (state) { case TelephonyManager.DATA_CONNECTED: //FIXME: Replace with a TelephonyManager call - phone.setDataEnabled(false); + phone.setUserDataEnabled(false); break; case TelephonyManager.DATA_DISCONNECTED: //FIXME: Replace with a TelephonyManager call - phone.setDataEnabled(true); + phone.setUserDataEnabled(true); break; default: // do nothing From 131d3b3c2f3c1bb7348564bbd311a66f38d7283c Mon Sep 17 00:00:00 2001 From: jackqdyulei Date: Fri, 5 Jan 2018 14:33:38 -0800 Subject: [PATCH 4/6] Add smart battery page for battery settings This page contains prefs for smart battery and app restriction. Bug: 71502850 Test: RunSettingsRoboTests Change-Id: I194af30cbc7b2496b10098fcb67f1116e0722310 --- res/layout/smart_battery_header.xml | 30 ++++++ res/values/strings.xml | 13 +++ res/xml/power_usage_summary.xml | 5 + res/xml/smart_battery_detail.xml | 38 +++++++ .../RestrictAppPreferenceController.java | 63 ++++++++++++ .../SmartBatteryPreferenceController.java | 54 ++++++++++ .../fuelgauge/SmartBatterySettings.java | 98 +++++++++++++++++++ .../search/SearchIndexableResources.java | 2 + .../RestrictAppPreferenceControllerTest.java | 88 +++++++++++++++++ 9 files changed, 391 insertions(+) create mode 100644 res/layout/smart_battery_header.xml create mode 100644 res/xml/smart_battery_detail.xml create mode 100644 src/com/android/settings/fuelgauge/RestrictAppPreferenceController.java create mode 100644 src/com/android/settings/fuelgauge/SmartBatteryPreferenceController.java create mode 100644 src/com/android/settings/fuelgauge/SmartBatterySettings.java create mode 100644 tests/robotests/src/com/android/settings/fuelgauge/RestrictAppPreferenceControllerTest.java diff --git a/res/layout/smart_battery_header.xml b/res/layout/smart_battery_header.xml new file mode 100644 index 00000000000..960f04ad380 --- /dev/null +++ b/res/layout/smart_battery_header.xml @@ -0,0 +1,30 @@ + + + + + + + diff --git a/res/values/strings.xml b/res/values/strings.xml index 74737ad05c7..79faf9b013e 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -4773,6 +4773,19 @@ Low battery capacity Battery can\'t provide good battery life + + Smart battery manager + + Auto-manage battery + + Automatically adjust power usage by apps based on usage + + Restricted apps + + + %1$d app + %1$d apps + Stop app? diff --git a/res/xml/power_usage_summary.xml b/res/xml/power_usage_summary.xml index 5d6c9e966ce..d7c3c3916da 100644 --- a/res/xml/power_usage_summary.xml +++ b/res/xml/power_usage_summary.xml @@ -38,6 +38,11 @@ android:key="battery_saver_summary" android:title="@string/battery_saver"/> + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/com/android/settings/fuelgauge/RestrictAppPreferenceController.java b/src/com/android/settings/fuelgauge/RestrictAppPreferenceController.java new file mode 100644 index 00000000000..7df0fb1b79a --- /dev/null +++ b/src/com/android/settings/fuelgauge/RestrictAppPreferenceController.java @@ -0,0 +1,63 @@ +/* + * 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; + +import android.app.AppOpsManager; +import android.content.Context; +import android.support.annotation.VisibleForTesting; +import android.support.v7.preference.Preference; + +import com.android.settings.R; +import com.android.settings.applications.LayoutPreference; +import com.android.settings.core.BasePreferenceController; + +import java.util.List; + +/** + * Controller to change and update the smart battery toggle + */ +public class RestrictAppPreferenceController extends BasePreferenceController { + @VisibleForTesting + static final String KEY_RESTRICT_APP = "restricted_app"; + + private AppOpsManager mAppOpsManager; + private List mPackageOps; + + public RestrictAppPreferenceController(Context context) { + super(context, KEY_RESTRICT_APP); + mAppOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE); + } + + @Override + public int getAvailabilityStatus() { + return AVAILABLE; + } + + @Override + public void updateState(Preference preference) { + super.updateState(preference); + mPackageOps = mAppOpsManager.getPackagesForOps( + new int[]{AppOpsManager.OP_RUN_ANY_IN_BACKGROUND}); + final int num = mPackageOps != null ? mPackageOps.size() : 0; + + preference.setSummary( + mContext.getResources().getQuantityString(R.plurals.restricted_app_summary, num, + num)); + } + +} diff --git a/src/com/android/settings/fuelgauge/SmartBatteryPreferenceController.java b/src/com/android/settings/fuelgauge/SmartBatteryPreferenceController.java new file mode 100644 index 00000000000..0002dac9db9 --- /dev/null +++ b/src/com/android/settings/fuelgauge/SmartBatteryPreferenceController.java @@ -0,0 +1,54 @@ +/* + * 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; + +import android.content.Context; +import android.support.annotation.VisibleForTesting; +import android.support.v7.preference.Preference; + +import com.android.settings.applications.LayoutPreference; +import com.android.settings.core.BasePreferenceController; + +/** + * Controller to change and update the smart battery toggle + */ +public class SmartBatteryPreferenceController extends BasePreferenceController implements + Preference.OnPreferenceChangeListener { + private static final String KEY_SMART_BATTERY = "smart_battery"; + + public SmartBatteryPreferenceController(Context context) { + super(context, KEY_SMART_BATTERY); + } + + @Override + public int getAvailabilityStatus() { + return AVAILABLE; + } + + @Override + public void updateState(Preference preference) { + super.updateState(preference); + } + + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + final boolean smartBatteryOn = (Boolean) newValue; + //TODO(b/71502850): use smart battery API here to update the state + return true; + } +} diff --git a/src/com/android/settings/fuelgauge/SmartBatterySettings.java b/src/com/android/settings/fuelgauge/SmartBatterySettings.java new file mode 100644 index 00000000000..5faaef41f60 --- /dev/null +++ b/src/com/android/settings/fuelgauge/SmartBatterySettings.java @@ -0,0 +1,98 @@ +/* + * 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; + +import android.content.Context; +import android.os.Bundle; +import android.provider.SearchIndexableResource; + +import com.android.internal.logging.nano.MetricsProto; +import com.android.settings.R; +import com.android.settings.dashboard.DashboardFragment; +import com.android.settings.search.BaseSearchIndexProvider; +import com.android.settingslib.core.AbstractPreferenceController; +import com.android.settingslib.widget.FooterPreferenceMixin; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Fragment to show smart battery and restricted app controls + */ +public class SmartBatterySettings extends DashboardFragment { + public static final String TAG = "SmartBatterySettings"; + + private final FooterPreferenceMixin mFooterPreferenceMixin = + new FooterPreferenceMixin(this, getLifecycle()); + + @Override + public void onCreate(Bundle icicle) { + super.onCreate(icicle); + mFooterPreferenceMixin.createFooterPreference().setTitle(R.string.battery_footer_summary); + } + + @Override + public int getMetricsCategory() { + return MetricsProto.MetricsEvent.FUELGAUGE_SMART_BATTERY; + } + + @Override + protected String getLogTag() { + return TAG; + } + + @Override + protected int getPreferenceScreenResId() { + return R.xml.smart_battery_detail; + } + + @Override + protected List getPreferenceControllers(Context context) { + return buildPreferenceControllers(context); + } + + private static List buildPreferenceControllers( + Context context) { + final List controllers = new ArrayList<>(); + controllers.add(new SmartBatteryPreferenceController(context)); + controllers.add(new RestrictAppPreferenceController(context)); + return controllers; + } + + public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = + new BaseSearchIndexProvider() { + @Override + public List getXmlResourcesToIndex( + Context context, boolean enabled) { + final SearchIndexableResource sir = new SearchIndexableResource(context); + sir.xmlResId = R.xml.smart_battery_detail; + return Arrays.asList(sir); + } + + @Override + public List getNonIndexableKeys(Context context) { + return super.getNonIndexableKeys(context); + } + + @Override + public List getPreferenceControllers( + Context context) { + return buildPreferenceControllers(context); + } + }; +} diff --git a/src/com/android/settings/search/SearchIndexableResources.java b/src/com/android/settings/search/SearchIndexableResources.java index 0207c94ad95..80ff032e1cc 100644 --- a/src/com/android/settings/search/SearchIndexableResources.java +++ b/src/com/android/settings/search/SearchIndexableResources.java @@ -50,6 +50,7 @@ import com.android.settings.enterprise.EnterprisePrivacySettings; import com.android.settings.fuelgauge.BatterySaverSettings; import com.android.settings.fuelgauge.PowerUsageAdvanced; import com.android.settings.fuelgauge.PowerUsageSummary; +import com.android.settings.fuelgauge.SmartBatterySettings; import com.android.settings.gestures.AssistGestureSettings; import com.android.settings.gestures.DoubleTapPowerSettings; import com.android.settings.gestures.DoubleTapScreenSettings; @@ -174,6 +175,7 @@ public final class SearchIndexableResources { addIndex(ZenModeBehaviorSettings.class); addIndex(ZenModeAutomationSettings.class); addIndex(NightDisplaySettings.class); + addIndex(SmartBatterySettings.class); } private SearchIndexableResources() { diff --git a/tests/robotests/src/com/android/settings/fuelgauge/RestrictAppPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/RestrictAppPreferenceControllerTest.java new file mode 100644 index 00000000000..c9441487b32 --- /dev/null +++ b/tests/robotests/src/com/android/settings/fuelgauge/RestrictAppPreferenceControllerTest.java @@ -0,0 +1,88 @@ +/* + * 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; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.spy; + +import android.app.AppOpsManager; +import android.content.Context; +import android.support.v7.preference.Preference; + +import com.android.settings.TestConfig; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; + +import java.util.ArrayList; +import java.util.List; + +@RunWith(RobolectricTestRunner.class) +@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) +public class RestrictAppPreferenceControllerTest { + + @Mock + private AppOpsManager mAppOpsManager; + @Mock + private AppOpsManager.PackageOps mPackageOps; + private List mPackageOpsList; + private RestrictAppPreferenceController mRestrictAppPreferenceController; + private Preference mPreference; + private Context mContext; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + + mContext = spy(RuntimeEnvironment.application); + doReturn(mAppOpsManager).when(mContext).getSystemService(Context.APP_OPS_SERVICE); + mRestrictAppPreferenceController = new RestrictAppPreferenceController(mContext); + mPackageOpsList = new ArrayList<>(); + mPreference = new Preference(mContext); + } + + @Test + public void testUpdateState_oneApp_showCorrectSummary() { + mPackageOpsList.add(mPackageOps); + doReturn(mPackageOpsList).when(mAppOpsManager).getPackagesForOps(any()); + + mRestrictAppPreferenceController.updateState(mPreference); + + assertThat(mPreference.getSummary()).isEqualTo("1 app"); + } + + @Test + public void testUpdateState_twoApps_showCorrectSummary() { + mPackageOpsList.add(mPackageOps); + mPackageOpsList.add(mPackageOps); + doReturn(mPackageOpsList).when(mAppOpsManager).getPackagesForOps(any()); + + mRestrictAppPreferenceController.updateState(mPreference); + + assertThat(mPreference.getSummary()).isEqualTo("2 apps"); + } + +} From 261c29c485dfe5848bb40244cf7cee4a08f452b7 Mon Sep 17 00:00:00 2001 From: jackqdyulei Date: Thu, 4 Jan 2018 14:55:13 -0800 Subject: [PATCH 5/6] Add wifi metered controls in wifi settings. 1. Add it in wifi detail page 2. Add it in wifi dialog 2. Remove it in "Mobile network" page Bug: 68030417 Test: RunSettingsRoboTests Change-Id: I2e001c55f3c6c75a660e429732dfbece97b0ca9e --- res/drawable/ic_attach_money_black_24dp.xml | 25 +++ res/layout/wifi_dialog.xml | 20 +++ res/values/arrays.xml | 12 ++ res/xml/data_usage_wifi.xml | 5 - res/xml/wifi_network_details_fragment.xml | 7 + .../datausage/DataUsageMeteredSettings.java | 150 ------------------ .../settings/datausage/DataUsageSummary.java | 26 --- .../search/SearchIndexableResources.java | 2 - .../settings/wifi/WifiConfigController.java | 7 +- .../WifiMeteredPreferenceController.java | 83 ++++++++++ .../details/WifiNetworkDetailsFragment.java | 9 +- .../datausage/DataUsageSummaryTest.java | 17 -- .../WifiMeteredPreferenceControllerTest.java | 89 +++++++++++ 13 files changed, 250 insertions(+), 202 deletions(-) create mode 100644 res/drawable/ic_attach_money_black_24dp.xml delete mode 100644 src/com/android/settings/datausage/DataUsageMeteredSettings.java create mode 100644 src/com/android/settings/wifi/details/WifiMeteredPreferenceController.java create mode 100644 tests/robotests/src/com/android/settings/wifi/details/WifiMeteredPreferenceControllerTest.java diff --git a/res/drawable/ic_attach_money_black_24dp.xml b/res/drawable/ic_attach_money_black_24dp.xml new file mode 100644 index 00000000000..12605fd9c66 --- /dev/null +++ b/res/drawable/ic_attach_money_black_24dp.xml @@ -0,0 +1,25 @@ + + + + + \ No newline at end of file diff --git a/res/layout/wifi_dialog.xml b/res/layout/wifi_dialog.xml index cfb6d9a6a5b..2c4a1edfdff 100644 --- a/res/layout/wifi_dialog.xml +++ b/res/layout/wifi_dialog.xml @@ -316,6 +316,26 @@ android:orientation="vertical" android:visibility="gone"> + + + + + + + + zen_mode_from_none + + Use network preference + Treat as metered + Treat as unmetered + + + + 0 + 1 + 2 + + diff --git a/res/xml/data_usage_wifi.xml b/res/xml/data_usage_wifi.xml index 607cee1851b..905b15a04f4 100644 --- a/res/xml/data_usage_wifi.xml +++ b/res/xml/data_usage_wifi.xml @@ -27,11 +27,6 @@ android:key="wifi_data_usage" android:title="@string/wifi_data_usage" /> - - diff --git a/res/xml/wifi_network_details_fragment.xml b/res/xml/wifi_network_details_fragment.xml index 8203bece42a..5e2745a6e51 100644 --- a/res/xml/wifi_network_details_fragment.xml +++ b/res/xml/wifi_network_details_fragment.xml @@ -49,6 +49,13 @@ android:icon="@drawable/ic_security_lock_24dp" android:title="@string/wifi_security" android:selectable="false"/> + + diff --git a/src/com/android/settings/datausage/DataUsageMeteredSettings.java b/src/com/android/settings/datausage/DataUsageMeteredSettings.java deleted file mode 100644 index 8bc7e04c3db..00000000000 --- a/src/com/android/settings/datausage/DataUsageMeteredSettings.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (C) 2016 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.datausage; - -import android.app.backup.BackupManager; -import android.content.Context; -import android.net.NetworkPolicyManager; -import android.net.wifi.WifiConfiguration; -import android.net.wifi.WifiManager; -import android.os.Bundle; -import android.provider.SearchIndexableResource; -import android.support.v7.preference.DropDownPreference; -import android.support.v7.preference.Preference; -import android.support.v7.preference.PreferenceCategory; -import android.text.TextUtils; - -import com.android.internal.logging.nano.MetricsProto.MetricsEvent; -import com.android.settings.R; -import com.android.settings.SettingsPreferenceFragment; -import com.android.settings.search.BaseSearchIndexProvider; -import com.android.settings.search.Indexable; -import com.android.settingslib.NetworkPolicyEditor; - -import java.util.Arrays; -import java.util.List; - -/** - * Panel to configure {@link WifiConfiguration#meteredOverride}. - */ -public class DataUsageMeteredSettings extends SettingsPreferenceFragment implements Indexable { - - private NetworkPolicyManager mPolicyManager; - private WifiManager mWifiManager; - - private NetworkPolicyEditor mPolicyEditor; - - private PreferenceCategory mMobileCategory; - private PreferenceCategory mWifiCategory; - private Preference mWifiDisabled; - - @Override - public int getMetricsCategory() { - return MetricsEvent.NET_DATA_USAGE_METERED; - } - - @Override - public void onCreate(Bundle icicle) { - super.onCreate(icicle); - final Context context = getActivity(); - - mPolicyManager = NetworkPolicyManager.from(context); - mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); - - mPolicyEditor = new NetworkPolicyEditor(mPolicyManager); - mPolicyEditor.read(); - - addPreferencesFromResource(R.xml.data_usage_metered_prefs); - mMobileCategory = (PreferenceCategory) findPreference("mobile"); - mWifiCategory = (PreferenceCategory) findPreference("wifi"); - mWifiDisabled = findPreference("wifi_disabled"); - - updateNetworks(context); - } - - private void updateNetworks(Context context) { - getPreferenceScreen().removePreference(mMobileCategory); - - mWifiCategory.removeAll(); - if (DataUsageUtils.hasWifiRadio(context) && mWifiManager.isWifiEnabled()) { - for (WifiConfiguration config : mWifiManager.getConfiguredNetworks()) { - final Preference pref = new MeteredPreference(getPrefContext(), config); - if (!TextUtils.isEmpty(pref.getTitle())) { - mWifiCategory.addPreference(pref); - } - } - } else { - mWifiCategory.addPreference(mWifiDisabled); - } - } - - private class MeteredPreference extends DropDownPreference { - private final WifiConfiguration mConfig; - - public MeteredPreference(Context context, WifiConfiguration config) { - super(context); - mConfig = config; - - setPersistent(false); - setEntries(new CharSequence[] { - getString(R.string.data_usage_metered_auto), - getString(R.string.data_usage_metered_yes), - getString(R.string.data_usage_metered_no), - }); - setEntryValues(new CharSequence[] { - Integer.toString(WifiConfiguration.METERED_OVERRIDE_NONE), - Integer.toString(WifiConfiguration.METERED_OVERRIDE_METERED), - Integer.toString(WifiConfiguration.METERED_OVERRIDE_NOT_METERED), - }); - setValue(Integer.toString(mConfig.meteredOverride)); - setTitle(NetworkPolicyManager.resolveNetworkId(mConfig)); - setSummary(getEntries()[mConfig.meteredOverride]); - - setOnPreferenceChangeListener(new OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange(Preference preference, Object newValue) { - mConfig.meteredOverride = Integer.parseInt((String) newValue); - setSummary(getEntries()[mConfig.meteredOverride]); - - mWifiManager.updateNetwork(mConfig); - // Stage the backup of the SettingsProvider package which backs this up - BackupManager.dataChanged("com.android.providers.settings"); - return true; - } - }); - } - } - - /** - * For search - */ - public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = - new BaseSearchIndexProvider() { - @Override - public List getXmlResourcesToIndex(Context context, - boolean enabled) { - final SearchIndexableResource sir = new SearchIndexableResource(context); - sir.xmlResId = R.xml.data_usage_metered_prefs; - return Arrays.asList(sir); - } - - @Override - public List getNonIndexableKeys(Context context) { - final List result = super.getNonIndexableKeys(context); - result.add("mobile"); - return result; - } - }; -} diff --git a/src/com/android/settings/datausage/DataUsageSummary.java b/src/com/android/settings/datausage/DataUsageSummary.java index fe220221db5..b4d5f50ee04 100644 --- a/src/com/android/settings/datausage/DataUsageSummary.java +++ b/src/com/android/settings/datausage/DataUsageSummary.java @@ -77,8 +77,6 @@ public class DataUsageSummary extends DataUsageBase implements Indexable, DataUs // Wifi keys public static final String KEY_WIFI_USAGE_TITLE = "wifi_category"; public static final String KEY_WIFI_DATA_USAGE = "wifi_data_usage"; - public static final String KEY_NETWORK_RESTRICTIONS = "network_restrictions"; - private DataUsageController mDataUsageController; private DataUsageInfoController mDataInfoController; @@ -86,8 +84,6 @@ public class DataUsageSummary extends DataUsageBase implements Indexable, DataUs private Preference mLimitPreference; private NetworkTemplate mDefaultTemplate; private int mDataUsageTemplate; - private NetworkRestrictionsPreference mNetworkRestrictionPreference; - private WifiManager mWifiManager; private NetworkPolicyEditor mPolicyEditor; @Override @@ -101,7 +97,6 @@ public class DataUsageSummary extends DataUsageBase implements Indexable, DataUs final Context context = getContext(); NetworkPolicyManager policyManager = NetworkPolicyManager.from(context); - mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); mPolicyEditor = new NetworkPolicyEditor(policyManager); boolean hasMobileData = DataUsageUtils.hasMobileData(context); @@ -203,8 +198,6 @@ public class DataUsageSummary extends DataUsageBase implements Indexable, DataUs TemplatePreferenceCategory category = (TemplatePreferenceCategory) inflatePreferences(R.xml.data_usage_wifi); category.setTemplate(NetworkTemplate.buildTemplateWifiWildcard(), 0, services); - mNetworkRestrictionPreference = - (NetworkRestrictionsPreference) category.findPreference(KEY_NETWORK_RESTRICTIONS); } private void addEthernetSection() { @@ -293,8 +286,6 @@ public class DataUsageSummary extends DataUsageBase implements Indexable, DataUs mLimitPreference.setSummary(null); } - updateNetworkRestrictionSummary(mNetworkRestrictionPreference); - PreferenceScreen screen = getPreferenceScreen(); for (int i = 1; i < screen.getPreferenceCount(); i++) { ((TemplatePreferenceCategory) screen.getPreference(i)).pushTemplates(services); @@ -321,22 +312,6 @@ public class DataUsageSummary extends DataUsageBase implements Indexable, DataUs updateState(); } - @VisibleForTesting - void updateNetworkRestrictionSummary(NetworkRestrictionsPreference preference) { - if (preference == null) { - return; - } - mPolicyEditor.read(); - int count = 0; - for (WifiConfiguration config : mWifiManager.getConfiguredNetworks()) { - if (WifiConfiguration.isMetered(config, null)) { - count++; - } - } - preference.setSummary(getResources().getQuantityString( - R.plurals.network_restrictions_summary, count, count)); - } - private static class SummaryProvider implements SummaryLoader.SummaryProvider { @@ -409,7 +384,6 @@ public class DataUsageSummary extends DataUsageBase implements Indexable, DataUs if (!DataUsageUtils.hasWifiRadio(context)) { keys.add(KEY_WIFI_DATA_USAGE); - keys.add(KEY_NETWORK_RESTRICTIONS); } // This title is named Wifi, and will confuse users. diff --git a/src/com/android/settings/search/SearchIndexableResources.java b/src/com/android/settings/search/SearchIndexableResources.java index 0207c94ad95..03763672454 100644 --- a/src/com/android/settings/search/SearchIndexableResources.java +++ b/src/com/android/settings/search/SearchIndexableResources.java @@ -36,7 +36,6 @@ import com.android.settings.bluetooth.BluetoothSettings; import com.android.settings.connecteddevice.AdvancedConnectedDeviceDashboardFragment; import com.android.settings.connecteddevice.ConnectedDeviceDashboardFragment; import com.android.settings.connecteddevice.ConnectedDeviceDashboardFragmentOld; -import com.android.settings.datausage.DataUsageMeteredSettings; import com.android.settings.datausage.DataUsageSummary; import com.android.settings.deletionhelper.AutomaticStorageManagerSettings; import com.android.settings.development.DevelopmentSettingsDashboardFragment; @@ -110,7 +109,6 @@ public final class SearchIndexableResources { addIndex(BluetoothSettings.class); addIndex(SimSettings.class); addIndex(DataUsageSummary.class); - addIndex(DataUsageMeteredSettings.class); addIndex(ScreenZoomSettings.class); addIndex(DisplaySettings.class); addIndex(AmbientDisplaySettings.class); diff --git a/src/com/android/settings/wifi/WifiConfigController.java b/src/com/android/settings/wifi/WifiConfigController.java index 4da7366696a..5e5d5ffaa00 100644 --- a/src/com/android/settings/wifi/WifiConfigController.java +++ b/src/com/android/settings/wifi/WifiConfigController.java @@ -146,11 +146,11 @@ public class WifiConfigController implements TextWatcher, private TextView mDns2View; private Spinner mProxySettingsSpinner; + private Spinner mMeteredSettingsSpinner; private TextView mProxyHostView; private TextView mProxyPortView; private TextView mProxyExclusionListView; private TextView mProxyPacView; - private CheckBox mSharedCheckBox; private IpAssignment mIpAssignment = IpAssignment.UNASSIGNED; @@ -208,6 +208,7 @@ public class WifiConfigController implements TextWatcher, mProxySettingsSpinner = (Spinner) mView.findViewById(R.id.proxy_settings); mProxySettingsSpinner.setOnItemSelectedListener(this); mSharedCheckBox = (CheckBox) mView.findViewById(R.id.shared); + mMeteredSettingsSpinner = mView.findViewById(R.id.metered_settings); if (mAccessPoint == null) { // new network mConfigUi.setTitle(R.string.wifi_add_network); @@ -237,6 +238,7 @@ public class WifiConfigController implements TextWatcher, boolean showAdvancedFields = false; if (mAccessPoint.isSaved()) { WifiConfiguration config = mAccessPoint.getConfig(); + mMeteredSettingsSpinner.setSelection(config.meteredOverride); if (config.getIpAssignment() == IpAssignment.STATIC) { mIpSettingsSpinner.setSelection(STATIC_IP); showAdvancedFields = true; @@ -671,6 +673,9 @@ public class WifiConfigController implements TextWatcher, config.setIpConfiguration( new IpConfiguration(mIpAssignment, mProxySettings, mStaticIpConfiguration, mHttpProxy)); + if (mMeteredSettingsSpinner != null) { + config.meteredOverride = mMeteredSettingsSpinner.getSelectedItemPosition(); + } return config; } diff --git a/src/com/android/settings/wifi/details/WifiMeteredPreferenceController.java b/src/com/android/settings/wifi/details/WifiMeteredPreferenceController.java new file mode 100644 index 00000000000..1a3d195a973 --- /dev/null +++ b/src/com/android/settings/wifi/details/WifiMeteredPreferenceController.java @@ -0,0 +1,83 @@ +/* + * 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.wifi.details; + +import android.app.backup.BackupManager; +import android.content.Context; +import android.net.wifi.WifiConfiguration; +import android.net.wifi.WifiManager; +import android.provider.Settings; +import android.support.annotation.VisibleForTesting; +import android.support.v14.preference.SwitchPreference; +import android.support.v7.preference.DropDownPreference; +import android.support.v7.preference.Preference; +import android.support.v7.preference.PreferenceScreen; +import android.text.TextUtils; + +import com.android.settings.core.BasePreferenceController; +import com.android.settings.core.PreferenceControllerMixin; +import com.android.settingslib.core.AbstractPreferenceController; + +/** + * {@link AbstractPreferenceController} that controls whether the wifi network is metered or not + */ +public class WifiMeteredPreferenceController extends BasePreferenceController implements + Preference.OnPreferenceChangeListener { + + private static final String KEY_WIFI_METERED = "metered"; + private WifiConfiguration mWifiConfiguration; + private WifiManager mWifiManager; + + public WifiMeteredPreferenceController(Context context, WifiConfiguration wifiConfiguration) { + super(context, KEY_WIFI_METERED); + mWifiConfiguration = wifiConfiguration; + mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); + } + + @Override + public void updateState(Preference preference) { + final DropDownPreference dropDownPreference = (DropDownPreference) preference; + final int meteredOverride = getMeteredOverride(); + dropDownPreference.setValue(Integer.toString(meteredOverride)); + updateSummary(dropDownPreference, meteredOverride); + } + + @Override + public int getAvailabilityStatus() { + return AVAILABLE; + } + + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + mWifiConfiguration.meteredOverride = Integer.parseInt((String) newValue); + mWifiManager.updateNetwork(mWifiConfiguration); + // Stage the backup of the SettingsProvider package which backs this up + BackupManager.dataChanged("com.android.providers.settings"); + updateSummary((DropDownPreference) preference, getMeteredOverride()); + return true; + } + + @VisibleForTesting + int getMeteredOverride() { + // Wrap the meteredOverride since robolectric cannot recognize it + return mWifiConfiguration.meteredOverride; + } + + private void updateSummary(DropDownPreference preference, int meteredOverride) { + preference.setSummary(preference.getEntries()[meteredOverride]); + } +} diff --git a/src/com/android/settings/wifi/details/WifiNetworkDetailsFragment.java b/src/com/android/settings/wifi/details/WifiNetworkDetailsFragment.java index ea30b562f3c..9a5430bcd8b 100644 --- a/src/com/android/settings/wifi/details/WifiNetworkDetailsFragment.java +++ b/src/com/android/settings/wifi/details/WifiNetworkDetailsFragment.java @@ -20,10 +20,13 @@ import static com.android.settings.wifi.WifiSettings.WIFI_DIALOG_ID; import android.app.Dialog; import android.content.Context; import android.net.ConnectivityManager; +import android.net.NetworkPolicyManager; +import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiManager; import android.os.Bundle; import android.os.Handler; import android.os.Looper; +import android.support.v7.preference.DropDownPreference; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; @@ -122,6 +125,7 @@ public class WifiNetworkDetailsFragment extends DashboardFragment { @Override protected List getPreferenceControllers(Context context) { + final List controllers = new ArrayList<>(); ConnectivityManager cm = context.getSystemService(ConnectivityManager.class); mWifiDetailPreferenceController = WifiDetailPreferenceController.newInstance( mAccessPoint, @@ -133,6 +137,9 @@ public class WifiNetworkDetailsFragment extends DashboardFragment { context.getSystemService(WifiManager.class), mMetricsFeatureProvider); - return new ArrayList<>(Collections.singletonList(mWifiDetailPreferenceController)); + controllers.add(mWifiDetailPreferenceController); + controllers.add(new WifiMeteredPreferenceController(context, mAccessPoint.getConfig())); + + return controllers; } } diff --git a/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryTest.java b/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryTest.java index dc53ca104ea..c1221054c43 100644 --- a/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryTest.java +++ b/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryTest.java @@ -68,23 +68,6 @@ public class DataUsageSummaryTest { when(mManager.isNetworkSupported(anyInt())).thenReturn(true); } - @Test - public void testUpdateNetworkRestrictionSummary_shouldSetSummary() { - final DataUsageSummary dataUsageSummary = spy(new DataUsageSummary()); - final NetworkRestrictionsPreference preference = mock(NetworkRestrictionsPreference.class); - final NetworkPolicyEditor policyEditor = mock(NetworkPolicyEditor.class); - final WifiManager wifiManager = mock(WifiManager.class); - ReflectionHelpers.setField(dataUsageSummary, "mPolicyEditor", policyEditor); - ReflectionHelpers.setField(dataUsageSummary, "mWifiManager", wifiManager); - when(wifiManager.getConfiguredNetworks()).thenReturn(new ArrayList()); - doReturn(mContext.getResources()).when(dataUsageSummary).getResources(); - - dataUsageSummary.updateNetworkRestrictionSummary(preference); - - verify(preference).setSummary(mContext.getResources().getQuantityString( - R.plurals.network_restrictions_summary, 0, 0)); - } - @Test @Config(shadows = { SettingsShadowResources.class, diff --git a/tests/robotests/src/com/android/settings/wifi/details/WifiMeteredPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/wifi/details/WifiMeteredPreferenceControllerTest.java new file mode 100644 index 00000000000..f624bd57cdb --- /dev/null +++ b/tests/robotests/src/com/android/settings/wifi/details/WifiMeteredPreferenceControllerTest.java @@ -0,0 +1,89 @@ +/* + * 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.wifi.details; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.spy; + +import android.content.Context; +import android.net.wifi.WifiConfiguration; +import android.support.v7.preference.DropDownPreference; + +import com.android.settings.R; +import com.android.settings.TestConfig; +import com.android.settings.testutils.SettingsRobolectricTestRunner; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; + +@RunWith(SettingsRobolectricTestRunner.class) +@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) +public class WifiMeteredPreferenceControllerTest { + public static final int METERED_OVERRIDE_NONE = 0; + public static final int METERED_OVERRIDE_METERED = 1; + public static final int METERED_OVERRIDE_NOT_METERED = 2; + + @Mock + private WifiConfiguration mWifiConfiguration; + + private WifiMeteredPreferenceController mPreferenceController; + private Context mContext; + private DropDownPreference mDropDownPreference; + + @Before + public void setUp() { + mContext = RuntimeEnvironment.application; + + mPreferenceController = spy( + new WifiMeteredPreferenceController(mContext, mWifiConfiguration)); + mDropDownPreference = new DropDownPreference(mContext); + mDropDownPreference.setEntries(R.array.wifi_metered_entries); + mDropDownPreference.setEntryValues(R.array.wifi_metered_values); + } + + @Test + public void testUpdateState_wifiMetered_setCorrectValue() { + doReturn(METERED_OVERRIDE_METERED).when(mPreferenceController).getMeteredOverride(); + + mPreferenceController.updateState(mDropDownPreference); + + assertThat(mDropDownPreference.getEntry()).isEqualTo("Treat as metered"); + } + + @Test + public void testUpdateState_wifiNotMetered_setCorrectValue() { + doReturn(METERED_OVERRIDE_NOT_METERED).when(mPreferenceController).getMeteredOverride(); + + mPreferenceController.updateState(mDropDownPreference); + + assertThat(mDropDownPreference.getEntry()).isEqualTo("Treat as unmetered"); + } + + @Test + public void testUpdateState_wifiAuto_setCorrectValue() { + doReturn(METERED_OVERRIDE_NONE).when(mPreferenceController).getMeteredOverride(); + + mPreferenceController.updateState(mDropDownPreference); + + assertThat(mDropDownPreference.getEntry()).isEqualTo("Use network preference"); + } +} From 88017c845156eb269bfdc5a010e95b1306cda297 Mon Sep 17 00:00:00 2001 From: Fan Zhang Date: Tue, 9 Jan 2018 13:44:06 -0800 Subject: [PATCH 6/6] Tweak layouts for action button to match spec Change-Id: Ic59ee1f15f20dc431bc4a2c6df20b732842a6591 Fixes: 70903732 Test: visual --- res/layout/two_action_buttons.xml | 7 +++++-- res/values/strings.xml | 4 ++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/res/layout/two_action_buttons.xml b/res/layout/two_action_buttons.xml index 41bcfc36efd..23bb886c901 100644 --- a/res/layout/two_action_buttons.xml +++ b/res/layout/two_action_buttons.xml @@ -20,9 +20,9 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" - android:paddingTop="8dp" + android:paddingTop="24dp" android:paddingStart="68dp" - android:paddingEnd="8dp" + android:paddingEnd="24dp" android:orientation="horizontal"> + Add - TURN ON NOW + Turn on now - TURN OFF NOW + Turn off now Do Not Disturb is on until %s