From 3a4168360b94ac3fdefeafa2f4a39169b6905c1b Mon Sep 17 00:00:00 2001 From: Matthew Fritze Date: Wed, 15 Nov 2017 15:12:52 -0800 Subject: [PATCH] Add SettingsPrefController for Slices Adds a new abstraction layer between preference controllers and the AbstractPreferenceController. The layer is used to consolidate the logic for each the setting type for getting and setting values. This will be extended to support UI information for Slices. For reference how this fits into Slices, look at the like-named classes added in this prototype: ag/3221891 The changes in Search are as a transition into deprecation. The code for Search in Settings is out-of-date from the unbundled counterpart, and this change is made so that the current code behaves as normal. Test: robotests Bug: 67996707 Change-Id: Ib1faab706485039edad66119a27a3fd5cabe6009 --- .../core/BasePreferenceController.java | 159 ++++++++++++++++++ .../core/PreferenceControllerMixin.java | 5 + .../core/TogglePreferenceController.java | 64 +++++++ .../AutoBrightnessPreferenceController.java | 49 +++--- .../search/BaseSearchIndexProvider.java | 4 + .../search/DatabaseIndexingUtils.java | 44 ++--- .../search/indexing/IndexDataConverter.java | 7 +- .../core/BasePreferenceControllerTest.java | 120 +++++++++++++ .../core/TogglePreferenceControllerTest.java | 92 ++++++++++ ...utoBrightnessPreferenceControllerTest.java | 33 ++-- .../search/DatabaseIndexingUtilsTest.java | 44 +---- 11 files changed, 502 insertions(+), 119 deletions(-) create mode 100644 src/com/android/settings/core/BasePreferenceController.java create mode 100644 src/com/android/settings/core/TogglePreferenceController.java create mode 100644 tests/robotests/src/com/android/settings/core/BasePreferenceControllerTest.java create mode 100644 tests/robotests/src/com/android/settings/core/TogglePreferenceControllerTest.java diff --git a/src/com/android/settings/core/BasePreferenceController.java b/src/com/android/settings/core/BasePreferenceController.java new file mode 100644 index 00000000000..444cbe93608 --- /dev/null +++ b/src/com/android/settings/core/BasePreferenceController.java @@ -0,0 +1,159 @@ +/* + * Copyright (C) 2017 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.core; + +import android.annotation.IntDef; +import android.app.slice.Slice; +import android.content.Context; +import android.support.v7.preference.Preference; +import android.text.TextUtils; +import android.util.Log; + + +import com.android.settings.core.PreferenceControllerMixin; +import com.android.settings.search.ResultPayload; +import com.android.settings.search.SearchIndexableRaw; +import com.android.settingslib.core.AbstractPreferenceController; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.util.List; + +/** + * Abstract class to consolidate utility between preference controllers and act as an interface + * for Slices. The abstract classes that inherit from this class will act as the direct interfaces + * for each type when plugging into Slices. + */ +public abstract class BasePreferenceController extends AbstractPreferenceController { + + private static final String TAG = "SettingsPrefController"; + + @Retention(RetentionPolicy.SOURCE) + @IntDef({AVAILABLE, DISABLED_UNSUPPORTED, DISABLED_FOR_USER, DISABLED_DEPENDENT_SETTING, + UNAVAILABLE_UNKNOWN}) + public @interface AvailabilityStatus { + } + + /** + * The setting is available. + */ + public static final int AVAILABLE = 0; + + /** + * The setting is not supported by the device. + */ + public static final int DISABLED_UNSUPPORTED = 1; + + /** + * The setting cannot be changed by the current user. + */ + public static final int DISABLED_FOR_USER = 2; + + /** + * The setting has a dependency in the Settings App which is currently blocking access. + */ + public static final int DISABLED_DEPENDENT_SETTING = 3; + + /** + * A catch-all case for internal errors and inexplicable unavailability. + */ + public static final int UNAVAILABLE_UNKNOWN = 4; + + private final String mPreferenceKey; + + public BasePreferenceController(Context context, String preferenceKey) { + super(context); + mPreferenceKey = preferenceKey; + } + + /** + * @return {@AvailabilityStatus} for the Setting. This status is used to determine if the + * Setting should be shown or disabled in Settings. Further, it can be used to produce + * appropriate error / warning Slice in the case of unavailability. + *

+ * The status is used for the convenience methods: {@link #isAvailable()}, + * {@link #isSupported()} + */ + @AvailabilityStatus + public abstract int getAvailabilityStatus(); + + /** + * @return A slice for the corresponding setting. + */ + public abstract Slice getSettingSlice(); + + @Override + public String getPreferenceKey() { + return mPreferenceKey; + } + + @Override + public final boolean isAvailable() { + return getAvailabilityStatus() == AVAILABLE; + } + + /** + * @return {@code false} if the setting is not applicable to the device. This covers both + * settings which were only introduced in future versions of android, or settings that have + * hardware dependencies. + *

+ * Note that a return value of {@code true} does not mean that the setting is available. + */ + public final boolean isSupported() { + return getAvailabilityStatus() != DISABLED_UNSUPPORTED; + } + + /** + * Updates non-indexable keys for search provider. + * + * Called by SearchIndexProvider#getNonIndexableKeys + */ + public void updateNonIndexableKeys(List keys) { + if (this instanceof AbstractPreferenceController) { + if (!isAvailable()) { + final String key = getPreferenceKey(); + if (TextUtils.isEmpty(key)) { + Log.w(TAG, + "Skipping updateNonIndexableKeys due to empty key " + this.toString()); + return; + } + keys.add(key); + } + } + } + + /** + * Updates raw data for search provider. + * + * Called by SearchIndexProvider#getRawDataToIndex + */ + public void updateRawDataToIndex(List rawData) { + } + + /** + * @return the {@link ResultPayload} corresponding to the search result type for the preference. + * TODO (b/69808376) Remove this method. + * Do not extend this method. It will not launch with P. + */ + @Deprecated + public ResultPayload getResultPayload() { + return null; + } + + // TODO (b/69380366) Add Method to get preference UI + + // TODO (b/69380464) Add method to get intent + + // TODO (b/69380560) Add method to get broadcast intent +} \ No newline at end of file diff --git a/src/com/android/settings/core/PreferenceControllerMixin.java b/src/com/android/settings/core/PreferenceControllerMixin.java index 1c54af76884..23facbaeaa7 100644 --- a/src/com/android/settings/core/PreferenceControllerMixin.java +++ b/src/com/android/settings/core/PreferenceControllerMixin.java @@ -26,6 +26,7 @@ import java.util.List; /** * A controller mixin that adds mobile settings specific functionality + * TODO (b/69808530) Replace with BasePreferenceController. */ public interface PreferenceControllerMixin { @@ -60,7 +61,11 @@ public interface PreferenceControllerMixin { /** * @return the {@link ResultPayload} corresponding to the search result type for the preference. + * + * Do not rely on this method for intent-based or inline results. It will be removed in the + * unbundling effort. */ + @Deprecated default ResultPayload getResultPayload() { return null; } diff --git a/src/com/android/settings/core/TogglePreferenceController.java b/src/com/android/settings/core/TogglePreferenceController.java new file mode 100644 index 00000000000..03106d3204a --- /dev/null +++ b/src/com/android/settings/core/TogglePreferenceController.java @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2017 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.core; + +import android.app.slice.Slice; +import android.content.Context; +import android.support.v14.preference.SwitchPreference; +import android.support.v7.preference.Preference; + +/** + * Abstract class that consolidates logic for updating toggle controllers. + * It automatically handles the getting and setting of the switch UI element. + * Children of this class implement methods to get and set the underlying value of the setting. + */ +public abstract class TogglePreferenceController extends BasePreferenceController implements + Preference.OnPreferenceChangeListener { + + private static final String TAG = "TogglePrefController"; + + public TogglePreferenceController(Context context, String preferenceKey) { + super(context, preferenceKey); + } + + /** + * @return {@code true} if the Setting is enabled. + */ + public abstract boolean isChecked(); + + /** + * Set the Setting to {@param isChecked} + * + * @param isChecked Is {@true} when the setting should be enabled. + */ + public abstract void setChecked(boolean isChecked); + + @Override + public final void updateState(Preference preference) { + ((SwitchPreference) preference).setChecked(isChecked()); + } + + @Override + public final boolean onPreferenceChange(Preference preference, Object newValue) { + boolean auto = (Boolean) newValue; + setChecked(auto); + return true; + } + + @Override + public Slice getSettingSlice() { + // TODO + return null; + } +} \ No newline at end of file diff --git a/src/com/android/settings/display/AutoBrightnessPreferenceController.java b/src/com/android/settings/display/AutoBrightnessPreferenceController.java index f242022a7eb..d71a1f8035e 100644 --- a/src/com/android/settings/display/AutoBrightnessPreferenceController.java +++ b/src/com/android/settings/display/AutoBrightnessPreferenceController.java @@ -16,65 +16,54 @@ package com.android.settings.display; import android.content.Context; import android.content.Intent; import android.provider.Settings; -import android.support.v14.preference.SwitchPreference; -import android.support.v7.preference.Preference; import com.android.settings.DisplaySettings; -import com.android.settings.core.PreferenceControllerMixin; +import com.android.settings.core.TogglePreferenceController; import com.android.settings.search.DatabaseIndexingUtils; import com.android.settings.search.InlineSwitchPayload; import com.android.settings.search.ResultPayload; import com.android.settings.R; -import com.android.settingslib.core.AbstractPreferenceController; import static android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE; import static android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC; import static android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL; -public class AutoBrightnessPreferenceController extends AbstractPreferenceController implements - PreferenceControllerMixin, Preference.OnPreferenceChangeListener { - - private final String mAutoBrightnessKey; +public class AutoBrightnessPreferenceController extends TogglePreferenceController { private final String SYSTEM_KEY = SCREEN_BRIGHTNESS_MODE; private final int DEFAULT_VALUE = SCREEN_BRIGHTNESS_MODE_MANUAL; public AutoBrightnessPreferenceController(Context context, String key) { - super(context); - mAutoBrightnessKey = key; + super(context, key); } @Override - public boolean isAvailable() { - return mContext.getResources().getBoolean( - com.android.internal.R.bool.config_automatic_brightness_available); + public boolean isChecked() { + return Settings.System.getInt(mContext.getContentResolver(), + SYSTEM_KEY, DEFAULT_VALUE) != DEFAULT_VALUE; } @Override - public String getPreferenceKey() { - return mAutoBrightnessKey; - } - - @Override - public void updateState(Preference preference) { - int brightnessMode = Settings.System.getInt(mContext.getContentResolver(), - SYSTEM_KEY, DEFAULT_VALUE); - ((SwitchPreference) preference).setChecked(brightnessMode != DEFAULT_VALUE); - } - - @Override - public boolean onPreferenceChange(Preference preference, Object newValue) { - boolean auto = (Boolean) newValue; + public void setChecked(boolean isChecked) { Settings.System.putInt(mContext.getContentResolver(), SYSTEM_KEY, - auto ? SCREEN_BRIGHTNESS_MODE_AUTOMATIC : DEFAULT_VALUE); - return true; + isChecked ? SCREEN_BRIGHTNESS_MODE_AUTOMATIC : DEFAULT_VALUE); + } + + @Override + @AvailabilityStatus + public int getAvailabilityStatus() { + return mContext.getResources().getBoolean( + com.android.internal.R.bool.config_automatic_brightness_available) + ? AVAILABLE + : DISABLED_UNSUPPORTED; } @Override public ResultPayload getResultPayload() { + // TODO remove result payload final Intent intent = DatabaseIndexingUtils.buildSearchResultPageIntent(mContext, - DisplaySettings.class.getName(), mAutoBrightnessKey, + DisplaySettings.class.getName(), getPreferenceKey(), mContext.getString(R.string.display_settings)); return new InlineSwitchPayload(SYSTEM_KEY, diff --git a/src/com/android/settings/search/BaseSearchIndexProvider.java b/src/com/android/settings/search/BaseSearchIndexProvider.java index 0f02f49b8db..57233009993 100644 --- a/src/com/android/settings/search/BaseSearchIndexProvider.java +++ b/src/com/android/settings/search/BaseSearchIndexProvider.java @@ -27,6 +27,7 @@ import android.util.AttributeSet; import android.util.Log; import android.util.Xml; +import com.android.settings.core.BasePreferenceController; import com.android.settings.core.PreferenceControllerMixin; import com.android.settingslib.core.AbstractPreferenceController; @@ -71,6 +72,9 @@ public class BaseSearchIndexProvider implements Indexable.SearchIndexProvider { if (controller instanceof PreferenceControllerMixin) { ((PreferenceControllerMixin) controller) .updateNonIndexableKeys(nonIndexableKeys); + } else if (controller instanceof BasePreferenceController) { + ((BasePreferenceController) controller).updateNonIndexableKeys( + nonIndexableKeys); } else { throw new IllegalStateException(controller.getClass().getName() + " must implement " + PreferenceControllerMixin.class.getName()); diff --git a/src/com/android/settings/search/DatabaseIndexingUtils.java b/src/com/android/settings/search/DatabaseIndexingUtils.java index 39bcdf8497a..207d09fdb37 100644 --- a/src/com/android/settings/search/DatabaseIndexingUtils.java +++ b/src/com/android/settings/search/DatabaseIndexingUtils.java @@ -27,6 +27,7 @@ import android.util.Log; import com.android.internal.logging.nano.MetricsProto; import com.android.settings.SettingsActivity; import com.android.settings.Utils; +import com.android.settings.core.BasePreferenceController; import com.android.settings.core.PreferenceControllerMixin; import com.android.settingslib.core.AbstractPreferenceController; @@ -72,10 +73,11 @@ public class DatabaseIndexingUtils { * @return A map between {@link Uri}s and {@link PreferenceControllerMixin}s to get the payload * types for Settings. */ - public static Map getPreferenceControllerUriMap( + public static Map getPayloadKeyMap( String className, Context context) { + ArrayMap map = new ArrayMap<>(); if (context == null) { - return null; + return map; } final Class clazz = getIndexableClass(className); @@ -83,7 +85,7 @@ public class DatabaseIndexingUtils { if (clazz == null) { Log.d(TAG, "SearchIndexableResource '" + className + "' should implement the " + Indexable.class.getName() + " interface!"); - return null; + return map; } // Will be non null only for a Local provider implementing a @@ -94,44 +96,28 @@ public class DatabaseIndexingUtils { provider.getPreferenceControllers(context); if (controllers == null) { - return null; + return map; } - ArrayMap map = new ArrayMap<>(); - for (AbstractPreferenceController controller : controllers) { + ResultPayload payload; if (controller instanceof PreferenceControllerMixin) { - map.put(controller.getPreferenceKey(), (PreferenceControllerMixin) controller); + payload = ((PreferenceControllerMixin) controller).getResultPayload(); + + } else if (controller instanceof BasePreferenceController) { + payload = ((BasePreferenceController) controller).getResultPayload(); } else { throw new IllegalStateException(controller.getClass().getName() + " must implement " + PreferenceControllerMixin.class.getName()); } + if (payload != null) { + map.put(controller.getPreferenceKey(), payload); + } } return map; } - /** - * @param uriMap Map between the {@link PreferenceControllerMixin} keys - * and the controllers themselves. - * @param key The look-up key - * @return The Payload from the {@link PreferenceControllerMixin} specified by the key, - * if it exists. Otherwise null. - */ - public static ResultPayload getPayloadFromUriMap(Map uriMap, - String key) { - if (uriMap == null) { - return null; - } - - PreferenceControllerMixin controller = uriMap.get(key); - if (controller == null) { - return null; - } - - return controller.getResultPayload(); - } - public static Class getIndexableClass(String className) { final Class clazz; try { @@ -164,4 +150,4 @@ public class DatabaseIndexingUtils { } return null; } -} +} \ No newline at end of file diff --git a/src/com/android/settings/search/indexing/IndexDataConverter.java b/src/com/android/settings/search/indexing/IndexDataConverter.java index 65fa279ee7d..c40a46658ed 100644 --- a/src/com/android/settings/search/indexing/IndexDataConverter.java +++ b/src/com/android/settings/search/indexing/IndexDataConverter.java @@ -40,6 +40,7 @@ import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; import java.util.ArrayList; +import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -178,11 +179,11 @@ public class IndexDataConverter { final String intentTargetPackage = sir.intentTargetPackage; final String intentTargetClass = sir.intentTargetClass; - Map controllerUriMap = null; + Map controllerUriMap = new HashMap<>(); if (fragmentName != null) { controllerUriMap = DatabaseIndexingUtils - .getPreferenceControllerUriMap(fragmentName, context); + .getPayloadKeyMap(fragmentName, context); } headerTitle = XmlParserUtils.getDataTitle(context, attrs); @@ -249,7 +250,7 @@ public class IndexDataConverter { } // TODO (b/62254931) index primitives instead of payload - payload = DatabaseIndexingUtils.getPayloadFromUriMap(controllerUriMap, key); + payload = controllerUriMap.get(key); childFragment = XmlParserUtils.getDataChildFragment(context, attrs); builder.setSummaryOn(summary) diff --git a/tests/robotests/src/com/android/settings/core/BasePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/core/BasePreferenceControllerTest.java new file mode 100644 index 00000000000..d153e9a3e4a --- /dev/null +++ b/tests/robotests/src/com/android/settings/core/BasePreferenceControllerTest.java @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2017 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.core; + +import static com.android.settings.core.BasePreferenceController.AVAILABLE; +import static com.android.settings.core.BasePreferenceController + .DISABLED_DEPENDENT_SETTING; +import static com.android.settings.core.BasePreferenceController.DISABLED_FOR_USER; +import static com.android.settings.core.BasePreferenceController.DISABLED_UNSUPPORTED; +import static com.android.settings.core.BasePreferenceController.UNAVAILABLE_UNKNOWN; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Mockito.when; + +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.mockito.MockitoAnnotations; +import org.robolectric.annotation.Config; + +@RunWith(SettingsRobolectricTestRunner.class) +@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O) +public class BasePreferenceControllerTest { + + @Mock + BasePreferenceController mPreferenceController; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + } + + @Test + public void isAvailable_availableStatusAvailable_returnsTrue() { + when(mPreferenceController.getAvailabilityStatus()).thenReturn(AVAILABLE); + + assertThat(mPreferenceController.isAvailable()).isTrue(); + } + + @Test + public void isAvailable_availableStatusUnsupported_returnsFalse() { + when(mPreferenceController.getAvailabilityStatus()).thenReturn(DISABLED_UNSUPPORTED); + + assertThat(mPreferenceController.isAvailable()).isFalse(); + } + + @Test + public void isAvailable_availableStatusDisabled_returnsFalse() { + when(mPreferenceController.getAvailabilityStatus()).thenReturn(DISABLED_FOR_USER); + + assertThat(mPreferenceController.isAvailable()).isFalse(); + } + + @Test + public void isAvailable_availableStatusBlockedDependent_returnsFalse() { + when(mPreferenceController.getAvailabilityStatus()).thenReturn(DISABLED_DEPENDENT_SETTING); + + assertThat(mPreferenceController.isAvailable()).isFalse(); + } + + @Test + public void isAvailable_availableStatusUnavailable_returnsFalse() { + when(mPreferenceController.getAvailabilityStatus()).thenReturn(UNAVAILABLE_UNKNOWN); + + assertThat(mPreferenceController.isAvailable()).isFalse(); + } + + @Test + public void isSupported_availableStatusAvailable_returnsTrue() { + when(mPreferenceController.getAvailabilityStatus()).thenReturn(AVAILABLE); + + assertThat(mPreferenceController.isSupported()).isTrue(); + } + + @Test + public void isSupported_availableStatusUnsupported_returnsFalse() { + when(mPreferenceController.getAvailabilityStatus()).thenReturn(DISABLED_UNSUPPORTED); + + assertThat(mPreferenceController.isSupported()).isFalse(); + } + + @Test + public void isSupported_availableStatusDisabled_returnsTrue() { + when(mPreferenceController.getAvailabilityStatus()).thenReturn(DISABLED_FOR_USER); + + assertThat(mPreferenceController.isSupported()).isTrue(); + } + + @Test + public void isSupported_availableStatusDependentSetting_returnsTrue() { + when(mPreferenceController.getAvailabilityStatus()).thenReturn(DISABLED_DEPENDENT_SETTING); + + assertThat(mPreferenceController.isSupported()).isTrue(); + } + + @Test + public void isSupported_availableStatusUnavailable_returnsTrue() { + when(mPreferenceController.getAvailabilityStatus()).thenReturn(UNAVAILABLE_UNKNOWN); + + assertThat(mPreferenceController.isSupported()).isTrue(); + } +} diff --git a/tests/robotests/src/com/android/settings/core/TogglePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/core/TogglePreferenceControllerTest.java new file mode 100644 index 00000000000..b3df90aa06f --- /dev/null +++ b/tests/robotests/src/com/android/settings/core/TogglePreferenceControllerTest.java @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2017 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.core; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.content.Context; +import android.support.v14.preference.SwitchPreference; + +import com.android.settings.TestConfig; +import com.android.settings.core.TogglePreferenceController; +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.mockito.MockitoAnnotations; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; + +@RunWith(SettingsRobolectricTestRunner.class) +@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O) +public class TogglePreferenceControllerTest { + + @Mock + TogglePreferenceController mTogglePreferenceController; + + Context mContext; + SwitchPreference mPreference; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + mContext = RuntimeEnvironment.application; + mPreference = new SwitchPreference(mContext); + } + + @Test + public void testSetsPreferenceValue_setsChecked() { + when(mTogglePreferenceController.isChecked()).thenReturn(true); + mPreference.setChecked(false); + + mTogglePreferenceController.updateState(mPreference); + + assertThat(mPreference.isChecked()).isTrue(); + } + + @Test + public void testSetsPreferenceValue_setsNotChecked() { + when(mTogglePreferenceController.isChecked()).thenReturn(false); + mPreference.setChecked(true); + + mTogglePreferenceController.updateState(mPreference); + + assertThat(mPreference.isChecked()).isFalse(); + } + + @Test + public void testUpdatesPreferenceOnChange_turnsOn() { + boolean newValue = true; + + mTogglePreferenceController.onPreferenceChange(mPreference, newValue); + + verify(mTogglePreferenceController).setChecked(newValue); + } + + @Test + public void testUpdatesPreferenceOnChange_turnsOff() { + boolean newValue = false; + + mTogglePreferenceController.onPreferenceChange(mPreference, newValue); + + verify(mTogglePreferenceController).setChecked(newValue); + } +} diff --git a/tests/robotests/src/com/android/settings/display/AutoBrightnessPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/display/AutoBrightnessPreferenceControllerTest.java index b46441dff65..4acf6097939 100644 --- a/tests/robotests/src/com/android/settings/display/AutoBrightnessPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/display/AutoBrightnessPreferenceControllerTest.java @@ -19,6 +19,7 @@ package com.android.settings.display; import static android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE; import static android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC; import static android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL; + import static com.google.common.truth.Truth.assertThat; import android.content.ContentResolver; @@ -26,9 +27,6 @@ import android.content.Context; import android.provider.Settings; import com.android.settings.TestConfig; -import com.android.settings.search.InlinePayload; -import com.android.settings.search.InlineSwitchPayload; -import com.android.settings.search.ResultPayload; import com.android.settings.testutils.SettingsRobolectricTestRunner; import org.junit.Before; @@ -38,10 +36,9 @@ import org.mockito.Answers; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.annotation.Config; -import org.robolectric.shadows.ShadowApplication; @RunWith(SettingsRobolectricTestRunner.class) -@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) +@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O) public class AutoBrightnessPreferenceControllerTest { @Mock(answer = Answers.RETURNS_DEEP_STUBS) private Context mContext; @@ -73,34 +70,28 @@ public class AutoBrightnessPreferenceControllerTest { assertThat(mode).isEqualTo(SCREEN_BRIGHTNESS_MODE_MANUAL); } - @Test - public void testPreferenceController_ProperResultPayloadType() { - final Context context = ShadowApplication.getInstance().getApplicationContext(); - mController = new AutoBrightnessPreferenceController(context, PREFERENCE_KEY); - ResultPayload payload = mController.getResultPayload(); - assertThat(payload).isInstanceOf(InlineSwitchPayload.class); - } - @Test public void testSetValue_updatesCorrectly() { - int newValue = 1; + boolean newValue = true; ContentResolver resolver = mContext.getContentResolver(); - Settings.System.putInt(resolver, SCREEN_BRIGHTNESS_MODE, 0); + Settings.System.putInt(resolver, SCREEN_BRIGHTNESS_MODE, SCREEN_BRIGHTNESS_MODE_MANUAL); - ((InlinePayload) mController.getResultPayload()).setValue(mContext, newValue); - int updatedValue = Settings.System.getInt(resolver, SCREEN_BRIGHTNESS_MODE, -1); + mController.setChecked(newValue); + boolean updatedValue = Settings.System.getInt(resolver, SCREEN_BRIGHTNESS_MODE, -1) + != SCREEN_BRIGHTNESS_MODE_MANUAL; assertThat(updatedValue).isEqualTo(newValue); } @Test public void testGetValue_correctValueReturned() { - int currentValue = 1; ContentResolver resolver = mContext.getContentResolver(); - Settings.System.putInt(resolver, SCREEN_BRIGHTNESS_MODE, currentValue); + Settings.System.putInt(resolver, SCREEN_BRIGHTNESS_MODE, SCREEN_BRIGHTNESS_MODE_AUTOMATIC); - int newValue = ((InlinePayload) mController.getResultPayload()).getValue(mContext); + int newValue = mController.isChecked() ? + SCREEN_BRIGHTNESS_MODE_AUTOMATIC + : SCREEN_BRIGHTNESS_MODE_MANUAL; - assertThat(newValue).isEqualTo(currentValue); + assertThat(newValue).isEqualTo(SCREEN_BRIGHTNESS_MODE_AUTOMATIC); } } diff --git a/tests/robotests/src/com/android/settings/search/DatabaseIndexingUtilsTest.java b/tests/robotests/src/com/android/settings/search/DatabaseIndexingUtilsTest.java index 9ce725b7764..94ce4874ccd 100644 --- a/tests/robotests/src/com/android/settings/search/DatabaseIndexingUtilsTest.java +++ b/tests/robotests/src/com/android/settings/search/DatabaseIndexingUtilsTest.java @@ -20,18 +20,14 @@ package com.android.settings.search; import static com.google.common.truth.Truth.assertThat; import android.content.Context; -import android.util.ArrayMap; -import com.android.internal.hardware.AmbientDisplayConfiguration; import com.android.settings.TestConfig; -import com.android.settings.core.PreferenceControllerMixin; import com.android.settings.deviceinfo.SystemUpdatePreferenceController; 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.mockito.MockitoAnnotations; import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; @@ -43,8 +39,6 @@ import java.util.Map; public class DatabaseIndexingUtilsTest { private Context mContext; - @Mock - private AmbientDisplayConfiguration mAmbientDisplayConfiguration; @Before public void setUp() { @@ -54,44 +48,22 @@ public class DatabaseIndexingUtilsTest { @Test public void testGetPreferenceControllerUriMap_BadClassName_ReturnsNull() { - Map map = DatabaseIndexingUtils.getPreferenceControllerUriMap("dummy", mContext); - assertThat(map).isNull(); + Map map = DatabaseIndexingUtils.getPayloadKeyMap("dummy", mContext); + assertThat(map).isEmpty(); } @Test public void testGetPreferenceControllerUriMap_NullContext_ReturnsNull() { - Map map = DatabaseIndexingUtils.getPreferenceControllerUriMap("dummy", null); - assertThat(map).isNull(); - } - - @Test - public void testGetPreferenceControllerUriMap_CompatibleClass_ReturnsValidMap() { - final String className = "com.android.settings.system.SystemDashboardFragment"; - final Map map = - DatabaseIndexingUtils.getPreferenceControllerUriMap(className, mContext); - assertThat(map.get("system_update_settings")) - .isInstanceOf(SystemUpdatePreferenceController.class); + Map map = DatabaseIndexingUtils.getPayloadKeyMap("dummy", null); + assertThat(map).isEmpty(); } @Test public void testGetPayloadFromMap_NullMap_ReturnsNull() { - ResultPayload payload = DatabaseIndexingUtils.getPayloadFromUriMap(null, ""); + final String className = "com.android.settings.system.SystemDashboardFragment"; + final Map map = + DatabaseIndexingUtils.getPayloadKeyMap(className, mContext); + ResultPayload payload = map.get(null); assertThat(payload).isNull(); } - - @Test - public void testGetPayloadFromMap_MatchingKey_ReturnsPayload() { - final String key = "key"; - PreferenceControllerMixin prefController = new PreferenceControllerMixin() { - @Override - public ResultPayload getResultPayload() { - return new ResultPayload(null); - } - }; - ArrayMap map = new ArrayMap<>(); - map.put(key, prefController); - - ResultPayload payload = DatabaseIndexingUtils.getPayloadFromUriMap(map, key); - assertThat(payload).isInstanceOf(ResultPayload.class); - } }