From 2b1a88da3df42e4ec1cb2fb9814f7a440b3735f2 Mon Sep 17 00:00:00 2001 From: Matthew Fritze Date: Tue, 23 May 2017 09:42:33 -0700 Subject: [PATCH] Simplify InlineSwitchPayloads and generalize get/set method InlineSwitchPayload now assumes that all switches will be stored as 1 or 0, which simplifies the code. Moves Availability into ResultPayload, so that custom payloads can be created to set/get values which are more complicated than stotring ints (like bluetooth or DnD), and give more expressive reasons when unavailable. Bug: 62022517 Test: make RunSettingsRoboTests Change-Id: I87e6fc041bfd398e7daf6e6e479d502930d36f0f --- .../AutoBrightnessPreferenceController.java | 10 +- .../search/CursorToSearchResultConverter.java | 39 ++-- .../search/DatabaseIndexingManager.java | 1 + .../settings/search/InlinePayload.java | 83 +++++++- .../settings/search/InlineSwitchPayload.java | 119 +++++------ .../search/InlineSwitchViewHolder.java | 7 +- .../settings/search/ResultPayload.java | 31 +++ ...utoBrightnessPreferenceControllerTest.java | 31 ++- .../CursorToSearchResultConverterTest.java | 24 +-- .../search/DatabaseIndexingManagerTest.java | 1 - .../settings/search/DatabaseRowTest.java | 15 +- .../search/InlineSwitchPayloadTest.java | 201 +++++++++++++----- .../search/InlineSwitchViewHolderTest.java | 6 +- 13 files changed, 378 insertions(+), 190 deletions(-) diff --git a/src/com/android/settings/display/AutoBrightnessPreferenceController.java b/src/com/android/settings/display/AutoBrightnessPreferenceController.java index 0cff7556a77..f731264a907 100644 --- a/src/com/android/settings/display/AutoBrightnessPreferenceController.java +++ b/src/com/android/settings/display/AutoBrightnessPreferenceController.java @@ -19,15 +19,12 @@ import android.provider.Settings; import android.support.v14.preference.SwitchPreference; import android.support.v7.preference.Preference; -import android.util.ArrayMap; import com.android.settings.core.PreferenceController; import com.android.settings.search.DatabaseIndexingUtils; import com.android.settings.search.InlineSwitchPayload; import com.android.settings.search.ResultPayload; import com.android.settings.R; -import java.util.Map; - 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; @@ -71,15 +68,12 @@ public class AutoBrightnessPreferenceController extends PreferenceController imp @Override public ResultPayload getResultPayload() { - final Map valueMap = new ArrayMap<>(); - valueMap.put(SCREEN_BRIGHTNESS_MODE_AUTOMATIC, true); - valueMap.put(SCREEN_BRIGHTNESS_MODE_MANUAL, false); - final Intent intent = DatabaseIndexingUtils.buildSubsettingIntent(mContext, getClass().getName(), mAutoBrightnessKey, mContext.getString(R.string.display_settings)); return new InlineSwitchPayload(SCREEN_BRIGHTNESS_MODE, - ResultPayload.SettingsSource.SYSTEM, valueMap, intent); + ResultPayload.SettingsSource.SYSTEM, SCREEN_BRIGHTNESS_MODE_AUTOMATIC, intent, + isAvailable()); } } diff --git a/src/com/android/settings/search/CursorToSearchResultConverter.java b/src/com/android/settings/search/CursorToSearchResultConverter.java index 1a0f8560fe9..26b46ffa8f8 100644 --- a/src/com/android/settings/search/CursorToSearchResultConverter.java +++ b/src/com/android/settings/search/CursorToSearchResultConverter.java @@ -58,9 +58,9 @@ import static com.android.settings.search.SearchResult.TOP_RANK; * - {@link Drawable} icon * - {@link ResultPayload} payload */ -class CursorToSearchResultConverter { +public class CursorToSearchResultConverter { - private final String TAG = "CursorConverter"; + private static final String TAG = "CursorConverter"; private final Context mContext; @@ -103,6 +103,23 @@ class CursorToSearchResultConverter { return results; } + public static ResultPayload getUnmarshalledPayload(byte[] marshalledPayload, + int payloadType) { + try { + switch (payloadType) { + case ResultPayload.PayloadType.INTENT: + return ResultPayloadUtils.unmarshall(marshalledPayload, + ResultPayload.CREATOR); + case ResultPayload.PayloadType.INLINE_SWITCH: + return ResultPayloadUtils.unmarshall(marshalledPayload, + InlineSwitchPayload.CREATOR); + } + } catch (BadParcelableException e) { + Log.w(TAG, "Error creating parcelable: " + e); + } + return null; + } + private SearchResult buildSingleSearchResultFromCursor(SiteMapManager sitemapManager, Map contextMap, Cursor cursor, int baseRank) { final int docId = cursor.getInt(COLUMN_INDEX_ID); @@ -162,22 +179,6 @@ class CursorToSearchResultConverter { return icon; } - private ResultPayload getUnmarshalledPayload(byte[] unmarshalledPayload, int payloadType) { - try { - switch (payloadType) { - case ResultPayload.PayloadType.INTENT: - return ResultPayloadUtils.unmarshall(unmarshalledPayload, - ResultPayload.CREATOR); - case ResultPayload.PayloadType.INLINE_SWITCH: - return ResultPayloadUtils.unmarshall(unmarshalledPayload, - InlineSwitchPayload.CREATOR); - } - } catch (BadParcelableException e) { - Log.w(TAG, "Error creating parcelable: " + e); - } - return null; - } - private List getBreadcrumbs(SiteMapManager siteMapManager, Cursor cursor) { final String screenTitle = cursor.getString(COLUMN_INDEX_SCREEN_TITLE); final String screenClass = cursor.getString(COLUMN_INDEX_CLASS_NAME); @@ -209,4 +210,4 @@ class CursorToSearchResultConverter { } return baseRank; } -} +} \ No newline at end of file diff --git a/src/com/android/settings/search/DatabaseIndexingManager.java b/src/com/android/settings/search/DatabaseIndexingManager.java index 746ab8a399f..c681912e71a 100644 --- a/src/com/android/settings/search/DatabaseIndexingManager.java +++ b/src/com/android/settings/search/DatabaseIndexingManager.java @@ -803,6 +803,7 @@ public class DatabaseIndexingManager { entries = XmlParserUtils.getDataEntries(context, attrs); } + // TODO (b/62254931) index primitives instead of payload payload = DatabaseIndexingUtils.getPayloadFromUriMap(controllerUriMap, key); childFragment = XmlParserUtils.getDataChildFragment(context, attrs); diff --git a/src/com/android/settings/search/InlinePayload.java b/src/com/android/settings/search/InlinePayload.java index b2bb59d1bde..439f1110a29 100644 --- a/src/com/android/settings/search/InlinePayload.java +++ b/src/com/android/settings/search/InlinePayload.java @@ -19,30 +19,93 @@ package com.android.settings.search; import android.content.Intent; +import android.content.Context; +import android.os.Parcel; +import com.android.internal.annotations.VisibleForTesting; + /** * Abstract Payload for inline settings results. */ public abstract class InlinePayload extends ResultPayload { + + public static final int FALSE = 0; + public static final int TRUE = 1; + /** - * Defines the URI to access and store the Setting the inline result represents + * Defines the key to access and store the Setting the inline result represents. */ - public String settingsUri; + @VisibleForTesting + final String mSettingKey; /** * The UI type for the inline result. */ - @PayloadType public int inlineType; + @PayloadType final int mInlineType; /** * Defines where the Setting is stored. */ - @SettingsSource public int settingSource; + @SettingsSource final int mSettingSource; - public InlinePayload(String uri, @PayloadType int type, @SettingsSource int source, - Intent intent) { + /** + * True when the setting is available for the device. + */ + final boolean mIsDeviceSupported; + + /** + * @param key uniquely identifies the stored setting. + * @param payloadType of the setting being stored. + * @param source of the setting. Used to determine where to get and set the setting. + * @param intent to the setting page. + * @param isDeviceSupported is true when the setting is valid for the given device. + */ + public InlinePayload(String key, @PayloadType int payloadType, @SettingsSource int source, + Intent intent, boolean isDeviceSupported) { super(intent); - settingsUri = uri; - inlineType = type; - settingSource = source; + mSettingKey = key; + mInlineType = payloadType; + mSettingSource = source; + mIsDeviceSupported = isDeviceSupported; } -} + + InlinePayload(Parcel parcel) { + super((Intent) parcel.readParcelable(Intent.class.getClassLoader())); + mSettingKey = parcel.readString(); + mInlineType = parcel.readInt(); + mSettingSource = parcel.readInt(); + mIsDeviceSupported = parcel.readInt() == TRUE; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + super.writeToParcel(dest, flags); + dest.writeString(mSettingKey); + dest.writeInt(mInlineType); + dest.writeInt(mSettingSource); + dest.writeInt(mIsDeviceSupported ? TRUE : FALSE); + } + + /** + * @returns the status of the underlying setting. See {@link ResultPayload.Availability} for + * possible values. + */ + @Availability public int getAvailability() { + if (mIsDeviceSupported) { + return Availability.AVAILABLE; + } + return Availability.DISABLED_UNSUPPORTED; + } + + /** + * @returns the current value of the setting. + */ + public abstract int getValue(Context context); + + /** + * Attempts to set the setting value. + * + * @param newValue is the requested new value for the setting. + * @returns true when the setting was changed, and false otherwise. + */ + public abstract boolean setValue(Context context, int newValue); +} \ No newline at end of file diff --git a/src/com/android/settings/search/InlineSwitchPayload.java b/src/com/android/settings/search/InlineSwitchPayload.java index 8046b72d50b..a2320545fa9 100644 --- a/src/com/android/settings/search/InlineSwitchPayload.java +++ b/src/com/android/settings/search/InlineSwitchPayload.java @@ -23,37 +23,41 @@ import android.os.Parcel; import android.os.Parcelable; import android.provider.Settings; -import java.util.Map; - /** * Payload for inline Switch results. Mappings from integer to boolean. */ public class InlineSwitchPayload extends InlinePayload { - /** - * Maps Inline values to UI-consumable Values. - * For example, if you have a switch preference whose values are stored as ints, the two valid - * list of mappings would be: - * < (0,True), (1, false) > - * < (1,True), (0, false) > - */ - public final Map valueMap; - public InlineSwitchPayload(String newUri, @SettingsSource int settingsSource, - Map map, Intent intent) { - super(newUri, PayloadType.INLINE_SWITCH, settingsSource, intent); - valueMap = map; + /** + * Provides a mapping for how switches are stored. + * If mIsStandard is true, then (0 == false) and (1 == true) + * If mIsStandard is false, then (1 == false) and (0 == true) + */ + private boolean mIsStandard; + + /** + * + * @param key uniquely identifies the stored setting. + * @param source of the setting. Used to determine where to get and set the setting. + * @param onValue is the value stored as on for the switch. Should be 0 or 1. + * @param intent to the setting page. + * @param isDeviceSupported is true when the setting is valid for the given device. + */ + public InlineSwitchPayload(String key, @SettingsSource int source, + int onValue, Intent intent, boolean isDeviceSupported) { + super(key, PayloadType.INLINE_SWITCH, source, intent, isDeviceSupported); + // If on is stored as TRUE then the switch is standard. + mIsStandard = onValue == TRUE; } private InlineSwitchPayload(Parcel in) { - super(in.readString() /* Uri */ , in.readInt() /* Payload Type */, - in.readInt() /* Settings Source */, - (Intent) in.readParcelable(Intent.class.getClassLoader()) /* Intent */); - valueMap = in.readHashMap(Integer.class.getClassLoader()); + super(in); + mIsStandard = in.readInt() == TRUE; } @Override public int getType() { - return inlineType; + return mInlineType; } @Override @@ -63,11 +67,8 @@ public class InlineSwitchPayload extends InlinePayload { @Override public void writeToParcel(Parcel dest, int flags) { - dest.writeString(settingsUri); - dest.writeInt(inlineType); - dest.writeInt(settingSource); - dest.writeParcelable(mIntent, flags); - dest.writeMap(valueMap); + super.writeToParcel(dest, flags); + dest.writeInt(mIsStandard ? TRUE : FALSE); } public static final Parcelable.Creator CREATOR = @@ -83,71 +84,65 @@ public class InlineSwitchPayload extends InlinePayload { } }; - public boolean getSwitchValue(Context context) { - if (valueMap == null) { - throw new IllegalStateException("Value map is null"); - } - + @Override + public int getValue(Context context) { int settingsValue = -1; - switch(settingSource) { + switch(mSettingSource) { case SettingsSource.SECURE: settingsValue = Settings.Secure.getInt(context.getContentResolver(), - settingsUri, 0); + mSettingKey, -1); break; case SettingsSource.SYSTEM: settingsValue = Settings.System.getInt(context.getContentResolver(), - settingsUri, 0); + mSettingKey, -1); break; case SettingsSource.GLOBAL: settingsValue = Settings.Global.getInt(context.getContentResolver(), - settingsUri, 0); + mSettingKey, -1); break; } if (settingsValue == -1) { throw new IllegalStateException("Unable to find setting from uri: " - + settingsUri.toString()); + + mSettingKey.toString()); } - for (Integer key : valueMap.keySet()) { - if ((key == settingsValue)) { - return valueMap.get(key); - } - } + settingsValue = standardizeInput(settingsValue); - throw new IllegalStateException("No results matched the key: " + settingsValue); + return settingsValue; } - public void setSwitchValue(Context context, boolean isChecked) { - if (valueMap == null) { - throw new IllegalStateException("Value map is null"); - } - int switchValue = -1; - - for (Map.Entry pair : valueMap.entrySet()) { - if (pair.getValue() == isChecked) { - switchValue = pair.getKey(); - break; - } + @Override + public boolean setValue(Context context, int newValue) { + if (newValue != 0 && newValue != 1) { + throw new IllegalArgumentException("newValue should be 0 for off and 1 for on." + + "The passed value was: " + newValue); } - if (switchValue == -1) { - throw new IllegalStateException("Switch value is not set"); - } + newValue = standardizeInput(newValue); - switch(settingSource) { + switch(mSettingSource) { case SettingsSource.GLOBAL: - Settings.Global.putInt(context.getContentResolver(), settingsUri, switchValue); - return; + return Settings.Global.putInt(context.getContentResolver(), mSettingKey, newValue); case SettingsSource.SECURE: - Settings.Secure.putInt(context.getContentResolver(), settingsUri, switchValue); - return; + return Settings.Secure.putInt(context.getContentResolver(), mSettingKey, newValue); case SettingsSource.SYSTEM: - Settings.System.putInt(context.getContentResolver(), settingsUri, switchValue); - return; + return Settings.System.putInt(context.getContentResolver(), mSettingKey, newValue); case SettingsSource.UNKNOWN: - return; + return false; } + + return false; + } + + public boolean isStandard() { + return mIsStandard; + } + + private int standardizeInput(int value) { + return mIsStandard + ? value + : 1 - value; } } diff --git a/src/com/android/settings/search/InlineSwitchViewHolder.java b/src/com/android/settings/search/InlineSwitchViewHolder.java index 82d33d80362..162eb1a2a1c 100644 --- a/src/com/android/settings/search/InlineSwitchViewHolder.java +++ b/src/com/android/settings/search/InlineSwitchViewHolder.java @@ -52,13 +52,14 @@ public class InlineSwitchViewHolder extends SearchViewHolder { return; } final InlineSwitchPayload payload = (InlineSwitchPayload) result.payload; - switchView.setChecked(payload.getSwitchValue(mContext)); + switchView.setChecked(payload.getValue(mContext) == InlineSwitchPayload.TRUE); switchView.setOnCheckedChangeListener((buttonView, isChecked) -> { final Pair value = Pair.create( MetricsEvent.FIELD_SETTINGS_SEARCH_INLINE_RESULT_VALUE, isChecked ? 1L : 0L); - fragment.onSearchResultClicked(this, payload.settingsUri, value); - payload.setSwitchValue(mContext, isChecked); + fragment.onSearchResultClicked(this, payload.mSettingKey, value); + int newValue = isChecked ? InlineSwitchPayload.TRUE : InlineSwitchPayload.FALSE; + payload.setValue(mContext, newValue); }); } } diff --git a/src/com/android/settings/search/ResultPayload.java b/src/com/android/settings/search/ResultPayload.java index 2352ffd3d45..39688acd09c 100644 --- a/src/com/android/settings/search/ResultPayload.java +++ b/src/com/android/settings/search/ResultPayload.java @@ -57,6 +57,37 @@ public class ResultPayload implements Parcelable { int SAVED_QUERY = 3; } + /** + * Enumerates the possible values for the Availability of a setting. + */ + @IntDef({Availability.AVAILABLE, + Availability.DISABLED_DEPENDENCY, + Availability.DISABLED_UNSUPPORTED, + Availability.RESOURCE_CONTENTION}) + @Retention(RetentionPolicy.SOURCE) + public @interface Availability { + /** + * The setting is available. + */ + int AVAILABLE = 0; + + /** + * The setting has a dependency which is currently disabled, blocking access. + */ + int DISABLED_DEPENDENCY = 1; + + /** + * The setting is not supported by the device. + */ + int DISABLED_UNSUPPORTED = 2; + + /** + * The setting you are trying to change is being used by another application and cannot + * be changed until it is released by said application. + */ + int RESOURCE_CONTENTION = 3; + } + @IntDef({SettingsSource.UNKNOWN, SettingsSource.SYSTEM, SettingsSource.SECURE, SettingsSource.GLOBAL}) @Retention(RetentionPolicy.SOURCE) diff --git a/tests/robotests/src/com/android/settings/display/AutoBrightnessPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/display/AutoBrightnessPreferenceControllerTest.java index a7da8570aae..fae48731016 100644 --- a/tests/robotests/src/com/android/settings/display/AutoBrightnessPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/display/AutoBrightnessPreferenceControllerTest.java @@ -16,12 +16,15 @@ package com.android.settings.display; +import android.content.ContentResolver; import android.content.Context; import android.provider.Settings; import com.android.settings.SettingsRobolectricTestRunner; 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.search.ResultPayload.Availability; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -78,13 +81,25 @@ public class AutoBrightnessPreferenceControllerTest { } @Test - public void testPreferenceController_CorrectPayload() { - final Context context = ShadowApplication.getInstance().getApplicationContext(); - mController = new AutoBrightnessPreferenceController(context, PREFERENCE_KEY); - InlineSwitchPayload payload = (InlineSwitchPayload) mController.getResultPayload(); - assertThat(payload.settingsUri).isEqualTo("screen_brightness_mode"); - assertThat(payload.settingSource).isEqualTo(ResultPayload.SettingsSource.SYSTEM); - assertThat(payload.valueMap.get(1)).isEqualTo(true); - assertThat(payload.valueMap.get(0)).isEqualTo(false); + public void testSetValue_updatesCorrectly() { + int newValue = 1; + ContentResolver resolver = mContext.getContentResolver(); + Settings.System.putInt(resolver, SCREEN_BRIGHTNESS_MODE, 0); + + ((InlinePayload) mController.getResultPayload()).setValue(mContext, newValue); + int updatedValue = Settings.System.getInt(resolver, SCREEN_BRIGHTNESS_MODE, -1); + + assertThat(updatedValue).isEqualTo(newValue); + } + + @Test + public void testGetValue_correctValueReturned() { + int currentValue = 1; + ContentResolver resolver = mContext.getContentResolver(); + Settings.System.putInt(resolver, SCREEN_BRIGHTNESS_MODE, currentValue); + + int newValue = ((InlinePayload) mController.getResultPayload()).getValue(mContext); + + assertThat(newValue).isEqualTo(currentValue); } } diff --git a/tests/robotests/src/com/android/settings/search/CursorToSearchResultConverterTest.java b/tests/robotests/src/com/android/settings/search/CursorToSearchResultConverterTest.java index 514d598bd64..eb25141f378 100644 --- a/tests/robotests/src/com/android/settings/search/CursorToSearchResultConverterTest.java +++ b/tests/robotests/src/com/android/settings/search/CursorToSearchResultConverterTest.java @@ -23,7 +23,6 @@ import android.content.Intent; import android.database.Cursor; import android.database.MatrixCursor; import android.graphics.drawable.Drawable; -import android.util.ArrayMap; import com.android.settings.DisplaySettings; import com.android.settings.R; @@ -31,14 +30,9 @@ import com.android.settings.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; import com.android.settings.dashboard.SiteMapManager; import com.android.settings.gestures.SwipeToNotificationSettings; -import com.android.settings.search.CursorToSearchResultConverter; -import com.android.settings.search.DatabaseResultLoader; -import com.android.settings.search.InlineSwitchPayload; -import com.android.settings.search.ResultPayload; +import com.android.settings.search.ResultPayload.Availability; import com.android.settings.search.ResultPayload.PayloadType; -import com.android.settings.search.ResultPayloadUtils; -import com.android.settings.search.SearchResult; import com.android.settings.wifi.WifiSettings; import org.junit.Before; import org.junit.Test; @@ -221,14 +215,12 @@ public class CursorToSearchResultConverterTest { final String uri = "test.com"; final int type = ResultPayload.PayloadType.INLINE_SWITCH; final int source = ResultPayload.SettingsSource.SECURE; - final ArrayMap map = new ArrayMap<>(); - map.put(1, true); - map.put(0, false); final String intentKey = "key"; final String intentVal = "value"; final Intent intent = new Intent(); intent.putExtra(intentKey, intentVal); - final InlineSwitchPayload payload = new InlineSwitchPayload(uri, source, map, intent); + final InlineSwitchPayload payload = new InlineSwitchPayload(uri, source, 1 /* onValue */, + intent, true /* isDeviceSupported */); cursor.addRow(new Object[]{ KEY.hashCode(), // Doc ID @@ -251,11 +243,11 @@ public class CursorToSearchResultConverterTest { for (SearchResult result : results) { final InlineSwitchPayload newPayload = (InlineSwitchPayload) result.payload; final Intent rebuiltIntent = newPayload.getIntent(); - assertThat(newPayload.settingsUri).isEqualTo(uri); - assertThat(newPayload.inlineType).isEqualTo(type); - assertThat(newPayload.settingSource).isEqualTo(source); - assertThat(newPayload.valueMap.get(1)).isTrue(); - assertThat(newPayload.valueMap.get(0)).isFalse(); + assertThat(newPayload.mSettingKey).isEqualTo(uri); + assertThat(newPayload.mInlineType).isEqualTo(type); + assertThat(newPayload.mSettingSource).isEqualTo(source); + assertThat(newPayload.isStandard()).isTrue(); + assertThat(newPayload.getAvailability()).isEqualTo(Availability.AVAILABLE); assertThat(rebuiltIntent.getStringExtra(intentKey)).isEqualTo(intentVal); } } diff --git a/tests/robotests/src/com/android/settings/search/DatabaseIndexingManagerTest.java b/tests/robotests/src/com/android/settings/search/DatabaseIndexingManagerTest.java index 6bcefcabfc6..f06f0036bda 100644 --- a/tests/robotests/src/com/android/settings/search/DatabaseIndexingManagerTest.java +++ b/tests/robotests/src/com/android/settings/search/DatabaseIndexingManagerTest.java @@ -1089,7 +1089,6 @@ public class DatabaseIndexingManagerTest { } private void insertSpecialCase(String specialCase, boolean enabled, String key) { - ContentValues values = new ContentValues(); values.put(IndexDatabaseHelper.IndexColumns.DOCID, specialCase.hashCode()); values.put(IndexDatabaseHelper.IndexColumns.LOCALE, localeStr); diff --git a/tests/robotests/src/com/android/settings/search/DatabaseRowTest.java b/tests/robotests/src/com/android/settings/search/DatabaseRowTest.java index db4227b56ae..18f03166f3d 100644 --- a/tests/robotests/src/com/android/settings/search/DatabaseRowTest.java +++ b/tests/robotests/src/com/android/settings/search/DatabaseRowTest.java @@ -26,17 +26,12 @@ import com.android.settings.TestConfig; import com.android.settings.search.DatabaseIndexingManager.DatabaseRow; import com.android.settings.search.DatabaseIndexingManager.DatabaseRow.Builder; -import com.android.settings.search.InlineSwitchPayload; -import com.android.settings.search.ResultPayload; -import com.android.settings.search.ResultPayloadUtils; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; -import java.util.HashMap; - import static com.google.common.truth.Truth.assertThat; @RunWith(SettingsRobolectricTestRunner.class) @@ -118,15 +113,15 @@ public class DatabaseRowTest { @Test public void testRowWithInlinePayload_genericPayloadNotAdded() { final String URI = "test uri"; - final InlineSwitchPayload payload = new InlineSwitchPayload(URI, 0, - new HashMap(), null); + final InlineSwitchPayload payload = new InlineSwitchPayload(URI, 0 /* mSettingSource */, + 1 /* onValue */, null /* intent */, true /* isDeviceSupported */); mBuilder.setPayload(payload); final DatabaseRow row = generateRow(); final InlineSwitchPayload unmarshalledPayload = ResultPayloadUtils .unmarshall(row.payload, InlineSwitchPayload.CREATOR); assertThat(row.payloadType).isEqualTo(ResultPayload.PayloadType.INLINE_SWITCH); - assertThat(unmarshalledPayload.settingsUri).isEqualTo(URI); + assertThat(unmarshalledPayload.mSettingKey).isEqualTo(URI); } @Test @@ -137,8 +132,8 @@ public class DatabaseRowTest { final Intent intent = new Intent(); intent.setComponent(component); - final InlineSwitchPayload payload = new InlineSwitchPayload(URI, 0, - new HashMap(), intent); + final InlineSwitchPayload payload = new InlineSwitchPayload(URI, 0 /* mSettingSource */, + 1 /* onValue */, intent, true /* isDeviceSupported */); mBuilder.setPayload(payload); final DatabaseRow row = generateRow(); final InlineSwitchPayload unmarshalledPayload = ResultPayloadUtils diff --git a/tests/robotests/src/com/android/settings/search/InlineSwitchPayloadTest.java b/tests/robotests/src/com/android/settings/search/InlineSwitchPayloadTest.java index 7167df0b7ea..3615a6794a7 100644 --- a/tests/robotests/src/com/android/settings/search/InlineSwitchPayloadTest.java +++ b/tests/robotests/src/com/android/settings/search/InlineSwitchPayloadTest.java @@ -17,76 +17,57 @@ package com.android.settings.search; +import android.content.ContentResolver; import android.content.Intent; import android.os.Parcel; -import android.util.ArrayMap; +import android.provider.Settings; import android.content.Context; import com.android.settings.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; +import com.android.settings.search.ResultPayload.Availability; +import com.android.settings.search.ResultPayload.SettingsSource; +import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; -import org.robolectric.shadows.ShadowApplication; +import static android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE; import static com.google.common.truth.Truth.assertThat; -import static org.junit.Assert.fail; @RunWith(SettingsRobolectricTestRunner.class) @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) public class InlineSwitchPayloadTest { - @Test - public void testGetSwitch_EmptyMap_ExceptionThrown() { - final String uri = "test.com"; - final int source = ResultPayload.SettingsSource.SECURE; + private static final String DUMMY_SETTING = "inline_test"; + private static final int STANDARD_ON = 1; + private static final int FLIPPED_ON = 0; - final Context context = ShadowApplication.getInstance().getApplicationContext(); - InlineSwitchPayload payload = new InlineSwitchPayload(uri, source, null, null); - try { - payload.getSwitchValue(context); - fail("Should have thrown exception for null map"); - } catch (IllegalStateException e) { - assertThat(e).isNotNull(); - } - } + private Context mContext; - @Test - public void testGetSwitch_BadMap_ExceptionThrown() { - final String uri = "test.com"; - final int source = ResultPayload.SettingsSource.SECURE; - final ArrayMap map = new ArrayMap<>(); - - final Context context = ShadowApplication.getInstance().getApplicationContext(); - InlineSwitchPayload payload = new InlineSwitchPayload(uri, source, map, null); - try { - payload.getSwitchValue(context); - fail("Should have thrown exception for bad map"); - } catch (IllegalStateException e) { - assertThat(e).isNotNull(); - } + @Before + public void setUp() { + mContext = RuntimeEnvironment.application; } @Test public void testConstructor_DataRetained() { final String uri = "test.com"; final int type = ResultPayload.PayloadType.INLINE_SWITCH; - final int source = ResultPayload.SettingsSource.SECURE; - final ArrayMap map = new ArrayMap<>(); - map.put(1, true); - map.put(0, false); + final int source = SettingsSource.SECURE; final String intentKey = "key"; final String intentVal = "value"; final Intent intent = new Intent(); intent.putExtra(intentKey, intentVal); - InlineSwitchPayload payload = new InlineSwitchPayload(uri, source, map, intent); + InlineSwitchPayload payload = new InlineSwitchPayload(uri, source, 1, intent, true); final Intent retainedIntent = payload.getIntent(); - assertThat(payload.settingsUri).isEqualTo(uri); - assertThat(payload.inlineType).isEqualTo(type); - assertThat(payload.settingSource).isEqualTo(source); - assertThat(payload.valueMap.get(1)).isTrue(); - assertThat(payload.valueMap.get(0)).isFalse(); + assertThat(payload.mSettingKey).isEqualTo(uri); + assertThat(payload.mInlineType).isEqualTo(type); + assertThat(payload.mSettingSource).isEqualTo(source); + assertThat(payload.isStandard()).isTrue(); + assertThat(payload.getAvailability()).isEqualTo(ResultPayload.Availability.AVAILABLE); assertThat(retainedIntent.getStringExtra(intentKey)).isEqualTo(intentVal); } @@ -94,32 +75,150 @@ public class InlineSwitchPayloadTest { public void testParcelConstructor_DataRetained() { String uri = "test.com"; int type = ResultPayload.PayloadType.INLINE_SWITCH; - int source = ResultPayload.SettingsSource.SECURE; - final ArrayMap map = new ArrayMap<>(); - map.put(1, true); - map.put(0, false); + int source = SettingsSource.SECURE; final String intentKey = "key"; final String intentVal = "value"; final Intent intent = new Intent(); intent.putExtra(intentKey, intentVal); Parcel parcel = Parcel.obtain(); + parcel.writeParcelable(intent, 0); parcel.writeString(uri); parcel.writeInt(type); parcel.writeInt(source); - parcel.writeParcelable(intent, 0); - parcel.writeMap(map); + parcel.writeInt(InlineSwitchPayload.TRUE); + parcel.writeInt(InlineSwitchPayload.TRUE); parcel.setDataPosition(0); InlineSwitchPayload payload = InlineSwitchPayload.CREATOR.createFromParcel(parcel); final Intent builtIntent = payload.getIntent(); - assertThat(payload.settingsUri).isEqualTo(uri); - assertThat(payload.inlineType).isEqualTo(type); - assertThat(payload.settingSource).isEqualTo(source); - assertThat(payload.valueMap.get(1)).isTrue(); - assertThat(payload.valueMap.get(0)).isFalse(); + assertThat(payload.mSettingKey).isEqualTo(uri); + assertThat(payload.mInlineType).isEqualTo(type); + assertThat(payload.mSettingSource).isEqualTo(source); + assertThat(payload.isStandard()).isTrue(); + assertThat(payload.getAvailability()).isEqualTo(Availability.AVAILABLE); assertThat(builtIntent.getStringExtra(intentKey)).isEqualTo(intentVal); } + @Test + public void testGetSecure_returnsSecureSetting() { + InlineSwitchPayload payload = new InlineSwitchPayload(DUMMY_SETTING, SettingsSource.SECURE, + STANDARD_ON, null /* intent */, true); + int currentValue = 1; + Settings.Secure.putInt(mContext.getContentResolver(), DUMMY_SETTING, currentValue); + int newValue = payload.getValue(mContext); + + assertThat(newValue).isEqualTo(currentValue); + } + + @Test + public void testGetGlobal_returnsGlobalSetting() { + InlineSwitchPayload payload = new InlineSwitchPayload(DUMMY_SETTING, SettingsSource.GLOBAL, + STANDARD_ON, null /* intent */, true); + int currentValue = 1; + Settings.Global.putInt(mContext.getContentResolver(), DUMMY_SETTING, currentValue); + + int newValue = payload.getValue(mContext); + + assertThat(newValue).isEqualTo(currentValue); + } + + @Test + public void testGetSystem_returnsSystemSetting() { + InlineSwitchPayload payload = new InlineSwitchPayload(DUMMY_SETTING, SettingsSource.SYSTEM, + STANDARD_ON, null /* intent */, true); + int currentValue = 1; + Settings.System.putInt(mContext.getContentResolver(), DUMMY_SETTING, currentValue); + + int newValue = payload.getValue(mContext); + + assertThat(newValue).isEqualTo(currentValue); + } + + @Test + public void testSetSecure_updatesSecureSetting() { + InlineSwitchPayload payload = new InlineSwitchPayload(DUMMY_SETTING, SettingsSource.SECURE, + STANDARD_ON, null /* intent */, true); + int newValue = 1; + ContentResolver resolver = mContext.getContentResolver(); + Settings.Secure.putInt(resolver, SCREEN_BRIGHTNESS_MODE, 0); + + payload.setValue(mContext, newValue); + int updatedValue = Settings.System.getInt(resolver, DUMMY_SETTING, -1); + + assertThat(updatedValue).isEqualTo(newValue); + } + + @Test + public void testSetGlobal_updatesGlobalSetting() { + InlineSwitchPayload payload = new InlineSwitchPayload(DUMMY_SETTING, SettingsSource.GLOBAL, + STANDARD_ON, null /* intent */, true); + int newValue = 1; + ContentResolver resolver = mContext.getContentResolver(); + Settings.Global.putInt(resolver, SCREEN_BRIGHTNESS_MODE, 0); + + payload.setValue(mContext, newValue); + int updatedValue = Settings.Global.getInt(resolver, DUMMY_SETTING, -1); + + assertThat(updatedValue).isEqualTo(newValue); + } + + @Test + public void testSetSystem_updatesSystemSetting() { + InlineSwitchPayload payload = new InlineSwitchPayload(DUMMY_SETTING, SettingsSource.SYSTEM, + STANDARD_ON, null /* intent */, true); + int newValue = 1; + ContentResolver resolver = mContext.getContentResolver(); + Settings.System.putInt(resolver, SCREEN_BRIGHTNESS_MODE, 0); + + payload.setValue(mContext, newValue); + int updatedValue = Settings.System.getInt(resolver, DUMMY_SETTING, -1); + + assertThat(updatedValue).isEqualTo(newValue); + } + + @Test + public void testGetSystem_flippedSetting_returnsFlippedValue() { + // Stores 1s as 0s, and vis versa + InlineSwitchPayload payload = new InlineSwitchPayload(DUMMY_SETTING, SettingsSource.SYSTEM, + FLIPPED_ON, null /* intent */, true); + int currentValue = 1; + Settings.System.putInt(mContext.getContentResolver(), DUMMY_SETTING, currentValue); + + int newValue = payload.getValue(mContext); + + assertThat(newValue).isEqualTo(1 - currentValue); + } + + @Test + public void testSetSystem_flippedSetting_updatesToFlippedValue() { + // Stores 1s as 0s, and vis versa + InlineSwitchPayload payload = new InlineSwitchPayload(DUMMY_SETTING, SettingsSource.SYSTEM, + FLIPPED_ON, null /* intent */, true); + int newValue = 1; + ContentResolver resolver = mContext.getContentResolver(); + Settings.System.putInt(resolver, SCREEN_BRIGHTNESS_MODE, newValue); + + payload.setValue(mContext, newValue); + int updatedValue = Settings.System.getInt(resolver, DUMMY_SETTING, -1); + + assertThat(updatedValue).isEqualTo(1 - newValue); + } + + @Test(expected = IllegalArgumentException.class) + public void testSetSystem_negativeValue_ThrowsError() { + InlineSwitchPayload payload = new InlineSwitchPayload(DUMMY_SETTING, SettingsSource.SYSTEM, + STANDARD_ON, null /* intent */, true); + + payload.setValue(mContext, -1); + } + + @Test(expected = IllegalArgumentException.class) + public void testSetSystem_highValue_ThrowsError() { + InlineSwitchPayload payload = new InlineSwitchPayload(DUMMY_SETTING, SettingsSource.SYSTEM, + STANDARD_ON, null /* intent */, true); + + payload.setValue(mContext, 2); + } } diff --git a/tests/robotests/src/com/android/settings/search/InlineSwitchViewHolderTest.java b/tests/robotests/src/com/android/settings/search/InlineSwitchViewHolderTest.java index ce483a42e85..537aac45feb 100644 --- a/tests/robotests/src/com/android/settings/search/InlineSwitchViewHolderTest.java +++ b/tests/robotests/src/com/android/settings/search/InlineSwitchViewHolderTest.java @@ -86,7 +86,7 @@ public class InlineSwitchViewHolderTest { @Test public void testBindViewElements_AllUpdated() { - when(mPayload.getSwitchValue(any(Context.class))).thenReturn(true); + when(mPayload.getValue(any(Context.class))).thenReturn(1); SearchResult result = getSearchResult(); mHolder.onBind(mFragment, result); // Precondition: switch is on. @@ -102,10 +102,12 @@ public class InlineSwitchViewHolderTest { private SearchResult getSearchResult() { SearchResult.Builder builder = new SearchResult.Builder(); + builder.setTitle(TITLE) .setSummary(SUMMARY) .setRank(1) - .setPayload(new InlineSwitchPayload("", 0, null, null)) + .setPayload(new InlineSwitchPayload("" /* uri */, 0 /* mSettingSource */, + 1 /* onValue */, null /* intent */, true /* isDeviceSupported */)) .addBreadcrumbs(new ArrayList<>()) .setIcon(mIcon) .setPayload(mPayload)