Merge "Clean Up: Groundwork for making TypefaceCompat implementation for API24." into oc-support-26.0-dev
diff --git a/api/26.0.0-SNAPSHOT.txt b/api/26.0.0-SNAPSHOT.txt
index b2a6003..5e565a1 100644
--- a/api/26.0.0-SNAPSHOT.txt
+++ b/api/26.0.0-SNAPSHOT.txt
@@ -11086,6 +11086,7 @@
method protected int getPersistedInt(int);
method protected long getPersistedLong(long);
method protected java.lang.String getPersistedString(java.lang.String);
+ method public java.util.Set<java.lang.String> getPersistedStringSet(java.util.Set<java.lang.String>);
method public android.support.v7.preference.PreferenceDataStore getPreferenceDataStore();
method public android.support.v7.preference.PreferenceManager getPreferenceManager();
method public android.content.SharedPreferences getSharedPreferences();
@@ -11122,6 +11123,7 @@
method protected boolean persistInt(int);
method protected boolean persistLong(long);
method protected boolean persistString(java.lang.String);
+ method public boolean persistStringSet(java.util.Set<java.lang.String>);
method public void restoreHierarchyState(android.os.Bundle);
method public void saveHierarchyState(android.os.Bundle);
method public void setDefaultValue(java.lang.Object);
@@ -11182,11 +11184,13 @@
method public int getInt(java.lang.String, int);
method public long getLong(java.lang.String, long);
method public java.lang.String getString(java.lang.String, java.lang.String);
+ method public java.util.Set<java.lang.String> getStringSet(java.lang.String, java.util.Set<java.lang.String>);
method public void putBoolean(java.lang.String, boolean);
method public void putFloat(java.lang.String, float);
method public void putInt(java.lang.String, int);
method public void putLong(java.lang.String, long);
method public void putString(java.lang.String, java.lang.String);
+ method public void putStringSet(java.lang.String, java.util.Set<java.lang.String>);
}
public abstract class PreferenceDialogFragmentCompat extends android.support.v4.app.DialogFragment implements android.content.DialogInterface.OnClickListener {
diff --git a/compat/java/android/support/v4/content/res/ResourcesCompat.java b/compat/java/android/support/v4/content/res/ResourcesCompat.java
index f9468ec..134149d 100644
--- a/compat/java/android/support/v4/content/res/ResourcesCompat.java
+++ b/compat/java/android/support/v4/content/res/ResourcesCompat.java
@@ -198,25 +198,21 @@
// Use framework support.
return context.getResources().getFont(id);
}
- return loadFont(context, id, Typeface.NORMAL);
+ return loadFont(context, id, new TypedValue(), Typeface.NORMAL);
}
/** @hide */
@RestrictTo(LIBRARY_GROUP)
- public static Typeface getFont(@NonNull Context context, @FontRes int id, int style)
- throws NotFoundException {
+ public static Typeface getFont(@NonNull Context context, @FontRes int id, TypedValue value,
+ int style) throws NotFoundException {
if (context.isRestricted()) {
return null;
}
- if (BuildCompat.isAtLeastO()) {
- // Use framework support.
- return context.getResources().getFont(id);
- }
- return loadFont(context, id, style);
+ return loadFont(context, id, value, style);
}
- private static Typeface loadFont(@NonNull Context context, int id, int style) {
- final TypedValue value = new TypedValue();
+ private static Typeface loadFont(@NonNull Context context, int id, TypedValue value,
+ int style) {
final Resources resources = context.getResources();
resources.getValue(id, value, true);
Typeface typeface = loadFont(context, resources, value, id, style);
@@ -234,12 +230,17 @@
+ Integer.toHexString(id) + ") is not a Font: " + value);
}
+ final String file = value.string.toString();
+ if (!file.startsWith("res/")) {
+ // Early exit if the specified string is unlikely to the resource path.
+ return null;
+ }
+
Typeface cached = TypefaceCompat.findFromCache(wrapper, id, style);
if (cached != null) {
return cached;
}
- final String file = value.string.toString();
try {
if (file.toLowerCase().endsWith(".xml")) {
final XmlResourceParser rp = wrapper.getXml(id);
diff --git a/compat/tests/java/android/support/v4/content/res/ResourcesCompatTest.java b/compat/tests/java/android/support/v4/content/res/ResourcesCompatTest.java
index f715079..56f5ab4 100644
--- a/compat/tests/java/android/support/v4/content/res/ResourcesCompatTest.java
+++ b/compat/tests/java/android/support/v4/content/res/ResourcesCompatTest.java
@@ -289,12 +289,12 @@
@Test(expected = Resources.NotFoundException.class)
public void testGetFont_invalidResourceId() {
- ResourcesCompat.getFont(mContext, -1, Typeface.NORMAL);
+ ResourcesCompat.getFont(mContext, -1);
}
@Test
public void testGetFont_fontFile() {
- Typeface font = ResourcesCompat.getFont(mContext, R.font.samplefont, Typeface.NORMAL);
+ Typeface font = ResourcesCompat.getFont(mContext, R.font.samplefont);
assertNotNull(font);
assertNotSame(Typeface.DEFAULT, font);
@@ -302,7 +302,7 @@
@Test
public void testGetFont_xmlFile() {
- Typeface font = ResourcesCompat.getFont(mContext, R.font.samplexmlfont, Typeface.NORMAL);
+ Typeface font = ResourcesCompat.getFont(mContext, R.font.samplexmlfont);
assertNotNull(font);
assertNotSame(Typeface.DEFAULT, font);
@@ -312,13 +312,13 @@
public void testGetFont_invalidXmlFile() {
try {
assertNull(
- ResourcesCompat.getFont(mContext, R.font.invalid_xmlfamily, Typeface.NORMAL));
+ ResourcesCompat.getFont(mContext, R.font.invalid_xmlfamily));
} catch (Resources.NotFoundException e) {
// pass
}
try {
- assertNull(ResourcesCompat.getFont(mContext, R.font.invalid_xmlempty, Typeface.NORMAL));
+ assertNull(ResourcesCompat.getFont(mContext, R.font.invalid_xmlempty));
} catch (Resources.NotFoundException e) {
// pass
}
@@ -326,16 +326,16 @@
@Test
public void testGetFont_fontFileIsCached() {
- Typeface font = ResourcesCompat.getFont(mContext, R.font.samplefont, Typeface.NORMAL);
- Typeface font2 = ResourcesCompat.getFont(mContext, R.font.samplefont, Typeface.NORMAL);
+ Typeface font = ResourcesCompat.getFont(mContext, R.font.samplefont);
+ Typeface font2 = ResourcesCompat.getFont(mContext, R.font.samplefont);
assertSame(font, font2);
}
@Test
public void testGetFont_xmlFileIsCached() {
- Typeface font = ResourcesCompat.getFont(mContext, R.font.samplexmlfont, Typeface.NORMAL);
- Typeface font2 = ResourcesCompat.getFont(mContext, R.font.samplexmlfont, Typeface.NORMAL);
+ Typeface font = ResourcesCompat.getFont(mContext, R.font.samplexmlfont);
+ Typeface font2 = ResourcesCompat.getFont(mContext, R.font.samplexmlfont);
assertSame(font, font2);
}
diff --git a/compat/tests/java/android/support/v4/util/SimpleArrayMapTest.java b/compat/tests/java/android/support/v4/util/SimpleArrayMapTest.java
index 16df3b5..2a07272 100644
--- a/compat/tests/java/android/support/v4/util/SimpleArrayMapTest.java
+++ b/compat/tests/java/android/support/v4/util/SimpleArrayMapTest.java
@@ -16,7 +16,7 @@
import static org.junit.Assert.fail;
-import android.support.test.filters.SmallTest;
+import android.support.test.filters.LargeTest;
import android.support.test.runner.AndroidJUnit4;
import android.util.Log;
@@ -29,7 +29,7 @@
* Unit tests for SimpleArrayMap
*/
@RunWith(AndroidJUnit4.class)
-@SmallTest
+@LargeTest
public class SimpleArrayMapTest {
private static final String TAG = "SimpleArrayMapTest";
SimpleArrayMap<String, String> map = new SimpleArrayMap<>();
diff --git a/media-compat/java/android/support/v4/media/MediaBrowserServiceCompat.java b/media-compat/java/android/support/v4/media/MediaBrowserServiceCompat.java
index c2bff47..542e045 100644
--- a/media-compat/java/android/support/v4/media/MediaBrowserServiceCompat.java
+++ b/media-compat/java/android/support/v4/media/MediaBrowserServiceCompat.java
@@ -309,9 +309,11 @@
rootExtras = new Bundle();
rootExtras.putInt(EXTRA_SERVICE_VERSION, SERVICE_VERSION_CURRENT);
BundleCompat.putBinder(rootExtras, EXTRA_MESSENGER_BINDER, mMessenger.getBinder());
- IMediaSession extraBinder = mSession.getExtraBinder();
- BundleCompat.putBinder(rootExtras, EXTRA_SESSION_BINDER,
- extraBinder == null ? null : extraBinder.asBinder());
+ if (mSession != null) {
+ IMediaSession extraBinder = mSession.getExtraBinder();
+ BundleCompat.putBinder(rootExtras, EXTRA_SESSION_BINDER,
+ extraBinder == null ? null : extraBinder.asBinder());
+ }
}
BrowserRoot root = MediaBrowserServiceCompat.this.onGetRoot(
clientPackageName, clientUid, rootHints);
diff --git a/media-compat/tests/AndroidManifest.xml b/media-compat/tests/AndroidManifest.xml
index f8ebb8b..60b7890 100644
--- a/media-compat/tests/AndroidManifest.xml
+++ b/media-compat/tests/AndroidManifest.xml
@@ -41,6 +41,11 @@
<action android:name="android.media.browse.MediaBrowserService"/>
</intent-filter>
</service>
+ <service android:name="android.support.v4.media.StubMediaBrowserServiceCompatWithDelayedMediaSession">
+ <intent-filter>
+ <action android:name="android.media.browse.MediaBrowserService"/>
+ </intent-filter>
+ </service>
</application>
</manifest>
diff --git a/media-compat/tests/src/android/support/v4/media/MediaBrowserCompatTest.java b/media-compat/tests/src/android/support/v4/media/MediaBrowserCompatTest.java
index 5b85e10..20d6119 100644
--- a/media-compat/tests/src/android/support/v4/media/MediaBrowserCompatTest.java
+++ b/media-compat/tests/src/android/support/v4/media/MediaBrowserCompatTest.java
@@ -27,6 +27,7 @@
import android.content.ComponentName;
import android.os.Bundle;
+import android.support.test.filters.LargeTest;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
import android.support.testutils.PollingCheck;
@@ -369,7 +370,7 @@
}
@Test
- @SmallTest
+ @LargeTest
public void testUnsubscribeForMultipleSubscriptions() throws Exception {
createMediaBrowser(TEST_BROWSER_SERVICE);
connectMediaBrowserService();
@@ -417,7 +418,7 @@
}
@Test
- @SmallTest
+ @LargeTest
public void testUnsubscribeWithSubscriptionCallbackForMultipleSubscriptions() throws Exception {
createMediaBrowser(TEST_BROWSER_SERVICE);
connectMediaBrowserService();
diff --git a/media-compat/tests/src/android/support/v4/media/MediaBrowserServiceCompatTest.java b/media-compat/tests/src/android/support/v4/media/MediaBrowserServiceCompatTest.java
index abd4214..0640f4d 100644
--- a/media-compat/tests/src/android/support/v4/media/MediaBrowserServiceCompatTest.java
+++ b/media-compat/tests/src/android/support/v4/media/MediaBrowserServiceCompatTest.java
@@ -48,6 +48,11 @@
private static final ComponentName TEST_BROWSER_SERVICE = new ComponentName(
"android.support.mediacompat.test",
"android.support.v4.media.StubMediaBrowserServiceCompat");
+ private static final ComponentName TEST_BROWSER_SERVICE_DELAYED_MEDIA_SESSION =
+ new ComponentName(
+ "android.support.mediacompat.test",
+ "android.support.v4.media"
+ + ".StubMediaBrowserServiceCompatWithDelayedMediaSession");
private static final String TEST_KEY_1 = "key_1";
private static final String TEST_VALUE_1 = "value_1";
private static final String TEST_KEY_2 = "key_2";
@@ -64,6 +69,7 @@
private final SearchCallback mSearchCallback = new SearchCallback();
private MediaBrowserCompat mMediaBrowser;
+ private MediaBrowserCompat mMediaBrowserForDelayedMediaSession;
private StubMediaBrowserServiceCompat mMediaBrowserService;
private Bundle mRootHints;
@@ -371,6 +377,33 @@
assertEquals(val, browserRoot.getExtras().getString(key));
}
+
+ @Test
+ @SmallTest
+ public void testDelayedSetSessionToken() throws Exception {
+ final ConnectionCallbackForDelayedMediaSession callback =
+ new ConnectionCallbackForDelayedMediaSession();
+
+ getInstrumentation().runOnMainSync(new Runnable() {
+ @Override
+ public void run() {
+ mMediaBrowserForDelayedMediaSession =
+ new MediaBrowserCompat(getInstrumentation().getTargetContext(),
+ TEST_BROWSER_SERVICE_DELAYED_MEDIA_SESSION, callback, null);
+ }
+ });
+
+ synchronized (mWaitLock) {
+ mMediaBrowserForDelayedMediaSession.connect();
+ mWaitLock.wait(WAIT_TIME_FOR_NO_RESPONSE_MS);
+ assertEquals(0, callback.mConnectedCount);
+
+ StubMediaBrowserServiceCompatWithDelayedMediaSession.sInstance.callSetSessionToken();
+ mWaitLock.wait(TIME_OUT_MS);
+ assertEquals(1, callback.mConnectedCount);
+ }
+ }
+
private void assertRootHints(MediaItem item) {
Bundle rootHints = item.getDescription().getExtras();
assertNotNull(rootHints);
@@ -527,4 +560,18 @@
mData = null;
}
}
+
+ private class ConnectionCallbackForDelayedMediaSession extends
+ MediaBrowserCompat.ConnectionCallback {
+ private int mConnectedCount = 0;
+
+ @Override
+ public void onConnected() {
+ synchronized (mWaitLock) {
+ mConnectedCount++;
+ mWaitLock.notify();
+ }
+ }
+ };
+
}
diff --git a/media-compat/tests/src/android/support/v4/media/StubMediaBrowserServiceCompatWithDelayedMediaSession.java b/media-compat/tests/src/android/support/v4/media/StubMediaBrowserServiceCompatWithDelayedMediaSession.java
new file mode 100644
index 0000000..e93c940
--- /dev/null
+++ b/media-compat/tests/src/android/support/v4/media/StubMediaBrowserServiceCompatWithDelayedMediaSession.java
@@ -0,0 +1,62 @@
+/*
+ * 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 android.support.v4.media;
+
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.v4.media.session.MediaSessionCompat;
+
+import java.util.List;
+
+/**
+ * Stub implementation of {@link MediaBrowserServiceCompat}.
+ * This implementation does not call
+ * {@link MediaBrowserServiceCompat#setSessionToken(MediaSessionCompat.Token)} in its
+ * {@link android.app.Service#onCreate}.
+ */
+public class StubMediaBrowserServiceCompatWithDelayedMediaSession extends
+ MediaBrowserServiceCompat {
+
+ static StubMediaBrowserServiceCompatWithDelayedMediaSession sInstance;
+ private MediaSessionCompat mSession;
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ sInstance = this;
+ mSession = new MediaSessionCompat(
+ this, "StubMediaBrowserServiceCompatWithDelayedMediaSession");
+ }
+
+ @Nullable
+ @Override
+ public BrowserRoot onGetRoot(@NonNull String clientPackageName,
+ int clientUid, @Nullable Bundle rootHints) {
+ return new BrowserRoot("StubRootId", null);
+ }
+
+ @Override
+ public void onLoadChildren(@NonNull String parentId,
+ @NonNull Result<List<MediaBrowserCompat.MediaItem>> result) {
+ result.detach();
+ }
+
+ void callSetSessionToken() {
+ setSessionToken(mSession.getSessionToken());
+ }
+}
diff --git a/v14/preference/src/android/support/v14/preference/MultiSelectListPreference.java b/v14/preference/src/android/support/v14/preference/MultiSelectListPreference.java
index 6b394e6..f34b7dc 100644
--- a/v14/preference/src/android/support/v14/preference/MultiSelectListPreference.java
+++ b/v14/preference/src/android/support/v14/preference/MultiSelectListPreference.java
@@ -16,17 +16,12 @@
package android.support.v14.preference;
-import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
-
import android.content.Context;
-import android.content.SharedPreferences;
import android.content.res.TypedArray;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.ArrayRes;
import android.support.annotation.NonNull;
-import android.support.annotation.RestrictTo;
-import android.support.v4.content.SharedPreferencesCompat;
import android.support.v4.content.res.TypedArrayUtils;
import android.support.v7.preference.internal.AbstractMultiSelectListPreference;
import android.util.AttributeSet;
@@ -85,64 +80,6 @@
}
/**
- * Attempts to persist a set of Strings to the {@link android.content.SharedPreferences}.
- * <p>
- * This will check if this Preference is persistent, get an editor from
- * the {@link android.preference.PreferenceManager}, put in the strings, and check if we should
- * commit (and commit if so).
- *
- * @param values The values to persist.
- * @return True if the Preference is persistent. (This is not whether the
- * value was persisted, since we may not necessarily commit if there
- * will be a batch commit later.)
- * @see #getPersistedString
- *
- * @hide
- */
- @RestrictTo(LIBRARY_GROUP)
- protected boolean persistStringSet(Set<String> values) {
- if (shouldPersist()) {
- // Shouldn't store null
- if (values.equals(getPersistedStringSet(null))) {
- // It's already there, so the same as persisting
- return true;
- }
-
- SharedPreferences.Editor editor = getPreferenceManager().getSharedPreferences().edit();
- editor.putStringSet(getKey(), values);
- SharedPreferencesCompat.EditorCompat.getInstance().apply(editor);
- return true;
- }
- return false;
- }
-
- /**
- * Attempts to get a persisted set of Strings from the
- * {@link android.content.SharedPreferences}.
- * <p>
- * This will check if this Preference is persistent, get the SharedPreferences
- * from the {@link android.preference.PreferenceManager}, and get the value.
- *
- * @param defaultReturnValue The default value to return if either the
- * Preference is not persistent or the Preference is not in the
- * shared preferences.
- * @return The value from the SharedPreferences or the default return
- * value.
- * @see #persistStringSet(Set)
- *
- * @hide
- */
- @RestrictTo(LIBRARY_GROUP)
- protected Set<String> getPersistedStringSet(Set<String> defaultReturnValue) {
- if (!shouldPersist()) {
- return defaultReturnValue;
- }
-
- return getPreferenceManager().getSharedPreferences()
- .getStringSet(getKey(), defaultReturnValue);
- }
-
- /**
* Sets the human-readable entries to be shown in the list. This will be
* shown in subsequent dialogs.
* <p>
diff --git a/v7/appcompat/src/android/support/v7/widget/TintTypedArray.java b/v7/appcompat/src/android/support/v7/widget/TintTypedArray.java
index a67313f..b962013 100644
--- a/v7/appcompat/src/android/support/v7/widget/TintTypedArray.java
+++ b/v7/appcompat/src/android/support/v7/widget/TintTypedArray.java
@@ -30,6 +30,7 @@
import android.support.annotation.RestrictTo;
import android.support.annotation.StyleableRes;
import android.support.v4.content.res.ResourcesCompat;
+import android.support.v4.os.BuildCompat;
import android.support.v7.content.res.AppCompatResources;
import android.util.AttributeSet;
import android.util.TypedValue;
@@ -103,13 +104,17 @@
*/
@Nullable
public Typeface getFont(@StyleableRes int index, int style) {
- if (mWrapped.hasValue(index)) {
- final int resourceId = mWrapped.getResourceId(index, 0);
- if (resourceId != 0) {
- return ResourcesCompat.getFont(mContext, resourceId, style);
- }
+ if (BuildCompat.isAtLeastO()) {
+ return mWrapped.getFont(index);
}
- return null;
+ final int resourceId = mWrapped.getResourceId(index, 0);
+ if (resourceId == 0) {
+ return null;
+ }
+ if (mTypedValue == null) {
+ mTypedValue = new TypedValue();
+ }
+ return ResourcesCompat.getFont(mContext, resourceId, mTypedValue, style);
}
public int length() {
diff --git a/v7/preference/src/android/support/v7/preference/Preference.java b/v7/preference/src/android/support/v7/preference/Preference.java
index cc9bb3d..6b302fd 100644
--- a/v7/preference/src/android/support/v7/preference/Preference.java
+++ b/v7/preference/src/android/support/v7/preference/Preference.java
@@ -44,6 +44,7 @@
import java.util.ArrayList;
import java.util.List;
+import java.util.Set;
/**
* Represents the basic Preference UI building
@@ -1578,7 +1579,7 @@
}
/**
- * Attempts to get a persisted {@link String} if this Preference is persistent.
+ * Attempts to get a persisted set of Strings if this Preference is persistent.
*
* @param defaultReturnValue The default value to return if either the
* Preference is not persistent or the Preference is not in the
@@ -1600,6 +1601,59 @@
}
/**
+ * Attempts to persist a set of Strings if this Preference is persistent.
+ *
+ * <p>The returned value doesn't reflect whether the given value was persisted, since we may not
+ * necessarily commit if there will be a batch commit later.
+ *
+ * @param values the values to persist
+ * @return {@code true} if the Preference is persistent, {@code false} otherwise
+ * @see #getPersistedStringSet(Set)
+ */
+ public boolean persistStringSet(Set<String> values) {
+ if (!shouldPersist()) {
+ return false;
+ }
+
+ // Shouldn't store null
+ if (values.equals(getPersistedStringSet(null))) {
+ // It's already there, so the same as persisting
+ return true;
+ }
+
+ PreferenceDataStore dataStore = getPreferenceDataStore();
+ if (dataStore != null) {
+ dataStore.putStringSet(mKey, values);
+ } else {
+ SharedPreferences.Editor editor = mPreferenceManager.getEditor();
+ editor.putStringSet(mKey, values);
+ tryCommit(editor);
+ }
+ return true;
+ }
+
+ /**
+ * Attempts to get a persisted set of Strings if this Preference is persistent.
+ *
+ * @param defaultReturnValue the default value to return if either this Preference is not
+ * persistent or this Preference is not present
+ * @return the value from the storage or the default return value
+ * @see #persistStringSet(Set)
+ */
+ public Set<String> getPersistedStringSet(Set<String> defaultReturnValue) {
+ if (!shouldPersist()) {
+ return defaultReturnValue;
+ }
+
+ PreferenceDataStore dataStore = getPreferenceDataStore();
+ if (dataStore != null) {
+ return dataStore.getStringSet(mKey, defaultReturnValue);
+ }
+
+ return mPreferenceManager.getSharedPreferences().getStringSet(mKey, defaultReturnValue);
+ }
+
+ /**
* Attempts to persist an {@link Integer} if this Preference is persistent.
*
* <p>The returned value doesn't reflect whether the given value was persisted, since we may not
diff --git a/v7/preference/src/android/support/v7/preference/PreferenceDataStore.java b/v7/preference/src/android/support/v7/preference/PreferenceDataStore.java
index 137ae48..fa5de18 100644
--- a/v7/preference/src/android/support/v7/preference/PreferenceDataStore.java
+++ b/v7/preference/src/android/support/v7/preference/PreferenceDataStore.java
@@ -18,6 +18,8 @@
import android.support.annotation.Nullable;
+import java.util.Set;
+
/**
* A data store interface to be implemented and provided to the Preferences framework. This can be
* used to replace the default {@link android.content.SharedPreferences}, if needed.
@@ -54,6 +56,19 @@
}
/**
+ * Sets a set of Strings to the data store.
+ *
+ * <p>Once the value is set the data store is responsible for holding it.
+ *
+ * @param key the name of the preference to modify
+ * @param values the set of new values for the preference
+ * @see #getStringSet(String, Set<String>)
+ */
+ public void putStringSet(String key, @Nullable Set<String> values) {
+ throw new UnsupportedOperationException("Not implemented on this data store");
+ }
+
+ /**
* Sets an {@link Integer} value to the data store.
*
* <p>Once the value is set the data store is responsible for holding it.
@@ -109,7 +124,7 @@
* Retrieves a {@link String} value from the data store.
*
* @param key the name of the preference to retrieve
- * @param defValue value to return if this preference does not exist
+ * @param defValue value to return if this preference does not exist in the storage
* @return the value from the data store or the default return value
* @see #putString(String, String)
*/
@@ -119,10 +134,23 @@
}
/**
+ * Retrieves a set of Strings from the data store.
+ *
+ * @param key the name of the preference to retrieve
+ * @param defValues values to return if this preference does not exist in the storage
+ * @return the values from the data store or the default return values
+ * @see #putStringSet(String, Set<String>)
+ */
+ @Nullable
+ public Set<String> getStringSet(String key, @Nullable Set<String> defValues) {
+ return defValues;
+ }
+
+ /**
* Retrieves an {@link Integer} value from the data store.
*
* @param key the name of the preference to retrieve
- * @param defValue value to return if this preference does not exist
+ * @param defValue value to return if this preference does not exist in the storage
* @return the value from the data store or the default return value
* @see #putInt(String, int)
*/
@@ -134,7 +162,7 @@
* Retrieves a {@link Long} value from the data store.
*
* @param key the name of the preference to retrieve
- * @param defValue value to return if this preference does not exist
+ * @param defValue value to return if this preference does not exist in the storage
* @return the value from the data store or the default return value
* @see #putLong(String, long)
*/
@@ -146,7 +174,7 @@
* Retrieves a {@link Float} value from the data store.
*
* @param key the name of the preference to retrieve
- * @param defValue value to return if this preference does not exist
+ * @param defValue value to return if this preference does not exist in the storage
* @return the value from the data store or the default return value
* @see #putFloat(String, float)
*/
@@ -158,7 +186,7 @@
* Retrieves a {@link Boolean} value from the data store.
*
* @param key the name of the preference to retrieve
- * @param defValue value to return if this preference does not exist
+ * @param defValue value to return if this preference does not exist in the storage
* @return the value from the data store or the default return value
* @see #getBoolean(String, boolean)
*/
diff --git a/v7/preference/tests/src/android/support/v7/preference/tests/PreferenceDataStoreTest.java b/v7/preference/tests/src/android/support/v7/preference/tests/PreferenceDataStoreTest.java
index 82e7a17..5c0923f 100644
--- a/v7/preference/tests/src/android/support/v7/preference/tests/PreferenceDataStoreTest.java
+++ b/v7/preference/tests/src/android/support/v7/preference/tests/PreferenceDataStoreTest.java
@@ -21,12 +21,15 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import static org.mockito.AdditionalMatchers.or;
+import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Matchers.anyFloat;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyLong;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
+import static org.mockito.Matchers.isNull;
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.mock;
@@ -39,6 +42,7 @@
import android.content.SharedPreferences;
import android.support.test.InstrumentationRegistry;
import android.support.test.annotation.UiThreadTest;
+import android.support.test.espresso.core.deps.guava.collect.ImmutableSet;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
import android.support.v7.preference.CheckBoxPreference;
@@ -46,12 +50,16 @@
import android.support.v7.preference.PreferenceDataStore;
import android.support.v7.preference.PreferenceManager;
import android.support.v7.preference.PreferenceScreen;
+import android.support.v7.preference.tests.helpers.PreferenceWrapper;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
+import java.util.HashSet;
+import java.util.Set;
+
/**
* Tests for {@link PreferenceDataStore} API.
*/
@@ -88,13 +96,74 @@
mManager.getSharedPreferences().edit().remove(KEY).commit();
}
+ @Test
+ public void testThatDataStoreIsNullByDefault() {
+ Preference preference = new Preference(mContext);
+ mScreen.addPreference(preference);
+
+ assertNull(preference.getPreferenceDataStore());
+ assertNotNull(preference.getSharedPreferences());
+
+ assertNull(mManager.getPreferenceDataStore());
+ assertNotNull(mManager.getSharedPreferences());
+ }
+
+ @Test
+ public void testSetGetOnPreference() {
+ Preference preference = new Preference(mContext);
+
+ preference.setPreferenceDataStore(mDataStore);
+
+ assertEquals(mDataStore, preference.getPreferenceDataStore());
+ }
+
+ @Test
+ public void testSetGetOnPreferenceManager() {
+ mManager.setPreferenceDataStore(mDataStore);
+
+ assertEquals(mDataStore, mManager.getPreferenceDataStore());
+ assertNull(mManager.getSharedPreferences());
+ }
+
+ @Test
+ public void testSetOnPreferenceManagerGetOnPreference() {
+ Preference preference = new Preference(mContext);
+ mScreen.addPreference(preference);
+
+ mManager.setPreferenceDataStore(mDataStore);
+
+ assertEquals(mDataStore, preference.getPreferenceDataStore());
+ assertNull(preference.getSharedPreferences());
+ }
+
+ @Test
+ @UiThreadTest
+ public void testDataStoresHierarchy() {
+ mPreference.setPreferenceDataStore(mDataStore);
+ PreferenceDataStore secondaryDataStore = mock(PreferenceDataStore.class,
+ Mockito.CALLS_REAL_METHODS);
+ mManager.setPreferenceDataStore(secondaryDataStore);
+ mScreen.addPreference(mPreference);
+
+ mPreference.putString(TEST_STR);
+
+ // Check that the Preference returns the correct data store.
+ assertEquals(mDataStore, mPreference.getPreferenceDataStore());
+
+ // Check that the secondary data store assigned to the manager was NOT used.
+ verifyZeroInteractions(secondaryDataStore);
+
+ // Check that the primary data store assigned directly to the preference was used.
+ verify(mDataStore, atLeastOnce()).putString(eq(KEY), anyString());
+ }
+
/**
* Test that the initial value is taken from the data store (before the preference gets assigned
* to the preference hierarchy).
*/
@Test
@UiThreadTest
- public void testInitialValueIsTakenFromDSOnPref() {
+ public void testInitialValueIsFromDataStoreOnPreference() {
when(mDataStore.getBoolean(anyString(), anyBoolean())).thenReturn(true);
CheckBoxPreference pref = new CheckBoxPreference(mContext);
@@ -112,10 +181,10 @@
*/
@Test
@UiThreadTest
- public void testInitialValueIsTakenFromDSOnMgr() {
+ public void testInitialValueIsFromDataStoreOnPreferenceManager() {
when(mDataStore.getBoolean(anyString(), anyBoolean())).thenReturn(true);
- mManager.setPreferenceDataStore(mDataStore);
+ mManager.setPreferenceDataStore(mDataStore);
CheckBoxPreference pref = new CheckBoxPreference(mContext);
pref.setKey("CheckboxTestPref");
@@ -156,7 +225,9 @@
public void testGetStringWithDataStoreOnPref() {
mPreference.setPreferenceDataStore(mDataStore);
mScreen.addPreference(mPreference);
+
mPreference.getString(TEST_STR);
+
verify(mDataStore, atLeastOnce()).getString(eq(KEY), eq(TEST_STR));
}
@@ -165,7 +236,9 @@
public void testGetStringWithDataStoreOnMgr() {
mManager.setPreferenceDataStore(mDataStore);
mScreen.addPreference(mPreference);
+
mPreference.getString(TEST_STR);
+
verify(mDataStore, atLeastOnce()).getString(eq(KEY), eq(TEST_STR));
}
@@ -184,7 +257,61 @@
mSharedPref.edit().putString(KEY, TEST_WRONG_STR).commit();
mScreen.addPreference(mPreference);
mSharedPref.edit().remove(KEY).commit();
- assertEquals(TEST_DEFAULT_STR, mPreference.mDefaultValue);
+ assertEquals(TEST_DEFAULT_STR, mPreference.getDefaultValue());
+ }
+
+ @Test
+ @UiThreadTest
+ public void testPutStringSetWithDataStoreOnPref() {
+ mPreference.setPreferenceDataStore(mDataStore);
+ mScreen.addPreference(mPreference);
+ putStringSetTestCommon();
+ }
+
+ @Test
+ @UiThreadTest
+ public void testPutStringSetWithDataStoreOnMgr() {
+ mManager.setPreferenceDataStore(mDataStore);
+ mScreen.addPreference(mPreference);
+ putStringSetTestCommon();
+ }
+
+ private void putStringSetTestCommon() {
+ Set<String> testSet = ImmutableSet.of(TEST_STR);
+
+ mPreference.putStringSet(testSet);
+
+ verify(mDataStore, atLeast(0)).getStringSet(eq(KEY), or(isNull(Set.class), any(Set.class)));
+ verify(mDataStore, atLeastOnce()).putStringSet(eq(KEY),
+ or(isNull(Set.class), any(Set.class)));
+ verifyNoMoreInteractions(mDataStore);
+
+ // Test that the value was NOT propagated to SharedPreferences.
+ assertNull(mSharedPref.getStringSet(KEY, null));
+ }
+
+ @Test
+ @UiThreadTest
+ public void testGetStringSetWithDataStoreOnPref() {
+ mPreference.setPreferenceDataStore(mDataStore);
+ mScreen.addPreference(mPreference);
+ Set<String> testSet = new HashSet<>();
+
+ mPreference.getStringSet(testSet);
+
+ verify(mDataStore, atLeastOnce()).getStringSet(eq(KEY), eq(testSet));
+ }
+
+ @Test
+ @UiThreadTest
+ public void testGetStringSetWithDataStoreOnMgr() {
+ mManager.setPreferenceDataStore(mDataStore);
+ mScreen.addPreference(mPreference);
+ Set<String> testSet = new HashSet<>();
+
+ mPreference.getStringSet(testSet);
+
+ verify(mDataStore, atLeastOnce()).getStringSet(eq(KEY), eq(testSet));
}
@Test
@@ -219,7 +346,9 @@
public void testGetIntWithDataStoreOnPref() {
mPreference.setPreferenceDataStore(mDataStore);
mScreen.addPreference(mPreference);
+
mPreference.getInt(1);
+
verify(mDataStore, atLeastOnce()).getInt(eq(KEY), eq(1));
}
@@ -228,7 +357,9 @@
public void testGetIntWithDataStoreOnMgr() {
mManager.setPreferenceDataStore(mDataStore);
mScreen.addPreference(mPreference);
+
mPreference.getInt(1);
+
verify(mDataStore, atLeastOnce()).getInt(eq(KEY), eq(1));
}
@@ -264,7 +395,9 @@
public void testGetLongWithDataStoreOnPref() {
mPreference.setPreferenceDataStore(mDataStore);
mScreen.addPreference(mPreference);
+
mPreference.getLong(1L);
+
verify(mDataStore, atLeastOnce()).getLong(eq(KEY), eq(1L));
}
@@ -273,7 +406,9 @@
public void testGetLongWithDataStoreOnMgr() {
mManager.setPreferenceDataStore(mDataStore);
mScreen.addPreference(mPreference);
+
mPreference.getLong(1L);
+
verify(mDataStore, atLeastOnce()).getLong(eq(KEY), eq(1L));
}
@@ -309,7 +444,9 @@
public void testGetFloatWithDataStoreOnPref() {
mPreference.setPreferenceDataStore(mDataStore);
mScreen.addPreference(mPreference);
+
mPreference.getFloat(1f);
+
verify(mDataStore, atLeastOnce()).getFloat(eq(KEY), eq(1f));
}
@@ -318,7 +455,9 @@
public void testGetFloatWithDataStoreOnMgr() {
mManager.setPreferenceDataStore(mDataStore);
mScreen.addPreference(mPreference);
+
mPreference.getFloat(1f);
+
verify(mDataStore, atLeastOnce()).getFloat(eq(KEY), eq(1f));
}
@@ -354,7 +493,9 @@
public void testGetBooleanWithDataStoreOnPref() {
mPreference.setPreferenceDataStore(mDataStore);
mScreen.addPreference(mPreference);
+
mPreference.getBoolean(true);
+
verify(mDataStore, atLeastOnce()).getBoolean(eq(KEY), eq(true));
}
@@ -363,30 +504,12 @@
public void testGetBooleanWithDataStoreOnMgr() {
mManager.setPreferenceDataStore(mDataStore);
mScreen.addPreference(mPreference);
+
mPreference.getBoolean(true);
+
verify(mDataStore, atLeastOnce()).getBoolean(eq(KEY), eq(true));
}
- @Test
- @UiThreadTest
- public void testDataStoresHierarchy() {
- mPreference.setPreferenceDataStore(mDataStore);
- PreferenceDataStore secondaryDataStore = mock(PreferenceDataStore.class,
- Mockito.CALLS_REAL_METHODS);
- mManager.setPreferenceDataStore(secondaryDataStore);
- mScreen.addPreference(mPreference);
- mPreference.putString(TEST_STR);
-
- // Check that the Preference returns the correct data store.
- assertEquals(mDataStore, mPreference.getPreferenceDataStore());
-
- // Check that the secondary data store assigned to the manager was NOT used.
- verifyZeroInteractions(secondaryDataStore);
-
- // Check that the primary data store assigned directly to the preference was used.
- verify(mDataStore, atLeast(0)).getString(eq(KEY), anyString());
- }
-
/**
* When {@link PreferenceDataStore} is NOT assigned, the getter for SharedPreferences must not
* return null for Preference.
@@ -395,6 +518,7 @@
@UiThreadTest
public void testSharedPrefNotNullIfNoDS() {
mScreen.addPreference(mPreference);
+
assertNotNull(mPreference.getSharedPreferences());
}
@@ -416,7 +540,9 @@
@UiThreadTest
public void testSharedPrefNullIfWithDS() {
mScreen.addPreference(mPreference);
+
mPreference.setPreferenceDataStore(mDataStore);
+
assertNull(mPreference.getSharedPreferences());
}
@@ -428,64 +554,8 @@
@UiThreadTest
public void testSharedPrefNullIfWithDSMgr() {
mManager.setPreferenceDataStore(mDataStore);
+
assertNull(mManager.getSharedPreferences());
}
- /**
- * Wrapper to allow to easily call protected methods.
- */
- private static class PreferenceWrapper extends Preference {
-
- Object mDefaultValue;
-
- PreferenceWrapper(Context context) {
- super(context);
- }
-
- void putString(String value) {
- persistString(value);
- }
-
- String getString(String defaultValue) {
- return getPersistedString(defaultValue);
- }
-
- void putInt(int value) {
- persistInt(value);
- }
-
- int getInt(int defaultValue) {
- return getPersistedInt(defaultValue);
- }
-
- void putLong(long value) {
- persistLong(value);
- }
-
- long getLong(long defaultValue) {
- return getPersistedLong(defaultValue);
- }
-
- void putFloat(float value) {
- persistFloat(value);
- }
-
- float getFloat(float defaultValue) {
- return getPersistedFloat(defaultValue);
- }
-
- void putBoolean(boolean value) {
- persistBoolean(value);
- }
-
- boolean getBoolean(boolean defaultValue) {
- return getPersistedBoolean(defaultValue);
- }
-
- @Override
- protected void onSetInitialValue(boolean restorePersistedValue, Object defaultValue) {
- this.mDefaultValue = defaultValue;
- super.onSetInitialValue(restorePersistedValue, defaultValue);
- }
- }
}
diff --git a/v7/preference/tests/src/android/support/v7/preference/tests/PreferencePersistTest.java b/v7/preference/tests/src/android/support/v7/preference/tests/PreferencePersistTest.java
new file mode 100644
index 0000000..536e2a7
--- /dev/null
+++ b/v7/preference/tests/src/android/support/v7/preference/tests/PreferencePersistTest.java
@@ -0,0 +1,405 @@
+/*
+ * 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 android.support.v7.preference.tests;
+
+import static org.hamcrest.collection.IsIterableContainingInAnyOrder.containsInAnyOrder;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.annotation.UiThreadTest;
+import android.support.test.espresso.core.deps.guava.collect.ImmutableSet;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.v7.preference.PreferenceManager;
+import android.support.v7.preference.PreferenceScreen;
+import android.support.v7.preference.tests.helpers.PreferenceWrapper;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Set;
+
+/**
+ * Tests for {@link android.support.v7.preference.Preference} persist / retrieve logic.
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class PreferencePersistTest {
+
+ private static final String KEY = "TestPrefKey";
+
+ private static final float FLOAT_PRECISION = 0.01f;
+
+ private static final Set<String> TEST_STR_SET = ImmutableSet.of("a", "b");
+ private static final Set<String> TEST_STR_SET2 = ImmutableSet.of("c", "d");
+ private static final Set<String> TEST_DEFAULT_STR_SET = ImmutableSet.of("e");
+
+ private PreferenceWrapper mPreference;
+ private SharedPreferences mSharedPref;
+
+ @Before
+ @UiThreadTest
+ public void setup() {
+ Context context = InstrumentationRegistry.getTargetContext();
+ PreferenceManager manager = new PreferenceManager(context);
+ mSharedPref = manager.getSharedPreferences();
+
+ mPreference = new PreferenceWrapper(context);
+ mPreference.setKey(KEY);
+
+ PreferenceScreen screen = manager.createPreferenceScreen(context);
+ screen.addPreference(mPreference);
+
+ // Make sure that the key is not present in SharedPreferences to ensure tests
+ // correctness.
+ mSharedPref.edit().remove(KEY).apply();
+ assertNull(mSharedPref.getString(KEY, null));
+ }
+
+ @Test
+ @UiThreadTest
+ public void string_retrieveWhenEmpty_returnsDefault() {
+ final String expected = "Default";
+
+ String result = mPreference.getString(expected);
+
+ assertEquals(expected, result);
+ }
+
+ @Test
+ @UiThreadTest
+ public void string_persist_getsStoredToSharedPrefs() {
+ final String expected = "Test";
+
+ boolean wasPersisted = mPreference.putString(expected);
+
+ assertTrue(wasPersisted);
+ assertEquals(expected, mSharedPref.getString(KEY, null));
+ }
+
+ @Test
+ @UiThreadTest
+ public void string_persistWhileDisabled_notPersisted() {
+ mPreference.setPersistent(false);
+
+ boolean wasPersisted = mPreference.putString("Test");
+
+ assertFalse(wasPersisted);
+ assertNull(mSharedPref.getString(KEY, null));
+ }
+
+ @Test
+ @UiThreadTest
+ public void string_persistAndRetrieve_returnsPersistedValue() {
+ final String expected = "Test";
+
+ mPreference.putString(expected);
+ String result = mPreference.getString("Default");
+
+ assertEquals(expected, result);
+ }
+
+ @Test
+ @UiThreadTest
+ public void string_persistTwiceAndRetrieve_returnsSecondValue() {
+ final String expected = "Second";
+
+ mPreference.putString("First");
+ mPreference.putString(expected);
+ String result = mPreference.getString("Default");
+
+ assertEquals(expected, result);
+ }
+
+
+ @Test
+ @UiThreadTest
+ public void stringSet_retrieveWhenEmpty_returnsDefault() {
+ final Set<String> expected = TEST_DEFAULT_STR_SET;
+
+ Set<String> result = mPreference.getStringSet(expected);
+
+ assertThat(result, containsInAnyOrder(expected.toArray()));
+ }
+
+ @Test
+ @UiThreadTest
+ public void stringSet_persist_getsStoredToSharedPrefs() {
+ boolean wasPersisted = mPreference.putStringSet(TEST_DEFAULT_STR_SET);
+
+ assertTrue(wasPersisted);
+ assertThat(mSharedPref.getStringSet(KEY, null),
+ containsInAnyOrder(TEST_DEFAULT_STR_SET.toArray()));
+ }
+
+ @Test
+ @UiThreadTest
+ public void stringSet_persistWhileDisabled_notPersisted() {
+ mPreference.setPersistent(false);
+
+ boolean wasPersisted = mPreference.putStringSet(TEST_STR_SET);
+
+ assertFalse(wasPersisted);
+ assertNull(mSharedPref.getString(KEY, null));
+ }
+
+ @Test
+ @UiThreadTest
+ public void stringSet_persistAndRetrieve_returnsPersistedValue() {
+ final Set<String> expected = TEST_STR_SET;
+
+ mPreference.putStringSet(expected);
+ Set<String> result = mPreference.getStringSet(TEST_DEFAULT_STR_SET);
+
+ assertThat(result, containsInAnyOrder(expected.toArray()));
+ }
+
+ @Test
+ @UiThreadTest
+ public void stringSet_persistTwiceAndRetrieve_returnsSecondValue() {
+ final Set<String> expected = TEST_STR_SET2;
+
+ mPreference.putStringSet(TEST_STR_SET);
+ mPreference.putStringSet(expected);
+ Set<String> result = mPreference.getStringSet(TEST_DEFAULT_STR_SET);
+
+ assertThat(result, containsInAnyOrder(expected.toArray()));
+ }
+
+
+ @Test
+ @UiThreadTest
+ public void int_retrieveWhenEmpty_returnsDefault() {
+ final int expected = 1;
+ int result = mPreference.getInt(expected);
+
+ assertEquals(expected, result);
+ }
+
+ @Test
+ @UiThreadTest
+ public void int_persist_getsStoredToSharedPrefs() {
+ final int expected = 1;
+
+ boolean wasPersisted = mPreference.putInt(expected);
+
+ assertTrue(wasPersisted);
+ assertEquals(expected, mSharedPref.getInt(KEY, -1));
+ }
+
+ @Test
+ @UiThreadTest
+ public void int_persistWhileDisabled_notPersisted() {
+ mPreference.setPersistent(false);
+
+ boolean wasPersisted = mPreference.putInt(1);
+
+ assertFalse(wasPersisted);
+ assertEquals(-1, mSharedPref.getLong(KEY, -1));
+ }
+
+ @Test
+ @UiThreadTest
+ public void int_persistAndRetrieve_returnsPersistedValue() {
+ final int expected = 1;
+
+ mPreference.putInt(expected);
+ int result = mPreference.getInt(-1);
+
+ assertEquals(expected, result);
+ }
+
+ @Test
+ @UiThreadTest
+ public void int_persistTwiceAndRetrieve_returnsSecondValue() {
+ final int expected = 2;
+
+ mPreference.putInt(1);
+ mPreference.putInt(expected);
+ int result = mPreference.getInt(-1);
+
+ assertEquals(expected, result);
+ }
+
+
+ @Test
+ @UiThreadTest
+ public void long_retrieveWhenEmpty_returnsDefault() {
+ assertEquals(1, mPreference.getLong(1));
+ }
+
+ @Test
+ @UiThreadTest
+ public void long_persist_getsStoredToSharedPrefs() {
+ final long expected = 1;
+
+ boolean wasPersisted = mPreference.putLong(expected);
+
+ assertTrue(wasPersisted);
+ assertEquals(expected, mSharedPref.getLong(KEY, -1));
+ }
+
+ @Test
+ @UiThreadTest
+ public void long_persistWhileDisabled_notPersisted() {
+ mPreference.setPersistent(false);
+
+ boolean wasPersisted = mPreference.putLong(1);
+
+ assertFalse(wasPersisted);
+ assertEquals(-1, mSharedPref.getLong(KEY, -1));
+ }
+
+ @Test
+ @UiThreadTest
+ public void long_persistAndRetrieve_returnsPersistedValue() {
+ final long expected = 1;
+
+ mPreference.putLong(expected);
+ long result = mPreference.getLong(-1);
+
+ assertEquals(expected, result);
+ }
+
+ @Test
+ @UiThreadTest
+ public void long_persistTwiceAndRetrieve_returnsSecondValue() {
+ final long expected = 2;
+
+ mPreference.putLong(1);
+ mPreference.putLong(expected);
+ long result = mPreference.getLong(-1);
+
+ assertEquals(expected, result);
+ }
+
+
+ @Test
+ @UiThreadTest
+ public void float_retrieveWhenEmpty_returnsDefault() {
+ assertEquals(1, mPreference.getFloat(1), FLOAT_PRECISION);
+ }
+
+ @Test
+ @UiThreadTest
+ public void float_persist_getsStoredToSharedPrefs() {
+ final float expected = 1;
+
+ boolean wasPersisted = mPreference.putFloat(expected);
+
+ assertTrue(wasPersisted);
+ assertEquals(expected, mSharedPref.getFloat(KEY, -1), FLOAT_PRECISION);
+ }
+
+ @Test
+ @UiThreadTest
+ public void float_persistWhileDisabled_notPersisted() {
+ mPreference.setPersistent(false);
+
+ boolean wasPersisted = mPreference.putFloat(1);
+
+ assertFalse(wasPersisted);
+ assertEquals(-1, mSharedPref.getFloat(KEY, -1), FLOAT_PRECISION);
+ }
+
+ @Test
+ @UiThreadTest
+ public void float_persistAndRetrieve_returnsPersistedValue() {
+ final float expected = 1;
+
+ mPreference.putFloat(expected);
+ float result = mPreference.getFloat(-1);
+
+ assertEquals(expected, result, FLOAT_PRECISION);
+ }
+
+ @Test
+ @UiThreadTest
+ public void float_persistTwiceAndRetrieve_returnsSecondValue() {
+ final float expected = 2;
+
+ mPreference.putFloat(1);
+ mPreference.putFloat(expected);
+ float result = mPreference.getFloat(-1);
+
+ assertEquals(expected, result, FLOAT_PRECISION);
+ }
+
+
+ @Test
+ @UiThreadTest
+ public void boolean_retrieveWhenEmpty_returnsDefault() {
+ final boolean expected = true;
+
+ boolean result = mPreference.getBoolean(expected);
+
+ assertEquals(expected, result);
+ }
+
+ @Test
+ @UiThreadTest
+ public void boolean_persist_getsStoredToSharedPrefs() {
+ final boolean expected = true;
+
+ boolean wasPersisted = mPreference.putBoolean(expected);
+
+ assertTrue(wasPersisted);
+ assertEquals(expected, mSharedPref.getBoolean(KEY, !expected));
+ }
+
+ @Test
+ @UiThreadTest
+ public void boolean_persistWhileDisabled_notPersisted() {
+ mPreference.setPersistent(false);
+
+ boolean wasPersisted = mPreference.putBoolean(true);
+
+ assertFalse(wasPersisted);
+ assertEquals(false, mSharedPref.getBoolean(KEY, false));
+ }
+
+ @Test
+ @UiThreadTest
+ public void boolean_persistAndRetrieve_returnsPersistedValue() {
+ final boolean expected = true;
+
+ mPreference.putBoolean(expected);
+ boolean result = mPreference.getBoolean(!expected);
+
+ assertEquals(expected, result);
+ }
+
+ @Test
+ @UiThreadTest
+ public void boolean_persistTwiceAndRetrieve_returnsSecondValue() {
+ final boolean expected = false;
+
+ mPreference.putBoolean(!expected);
+ mPreference.putBoolean(expected);
+ boolean result = mPreference.getBoolean(!expected);
+
+ assertEquals(expected, result);
+ }
+
+}
diff --git a/v7/preference/tests/src/android/support/v7/preference/tests/helpers/PreferenceWrapper.java b/v7/preference/tests/src/android/support/v7/preference/tests/helpers/PreferenceWrapper.java
new file mode 100644
index 0000000..b2674a5
--- /dev/null
+++ b/v7/preference/tests/src/android/support/v7/preference/tests/helpers/PreferenceWrapper.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 android.support.v7.preference.tests.helpers;
+
+import android.content.Context;
+import android.support.v7.preference.Preference;
+
+import java.util.Set;
+
+/**
+ * Wrapper to allow to easily call protected methods.
+ */
+public final class PreferenceWrapper extends Preference {
+
+ Object mDefaultValue;
+
+ public PreferenceWrapper(Context context) {
+ super(context);
+ }
+
+ public Object getDefaultValue() {
+ return mDefaultValue;
+ }
+
+ public boolean putString(String value) {
+ return persistString(value);
+ }
+
+ public String getString(String defaultValue) {
+ return getPersistedString(defaultValue);
+ }
+
+ public boolean putStringSet(Set<String> values) {
+ return persistStringSet(values);
+ }
+
+ public Set<String> getStringSet(Set<String> defaultValues) {
+ return getPersistedStringSet(defaultValues);
+ }
+
+ public boolean putInt(int value) {
+ return persistInt(value);
+ }
+
+ public int getInt(int defaultValue) {
+ return getPersistedInt(defaultValue);
+ }
+
+ public boolean putLong(long value) {
+ return persistLong(value);
+ }
+
+ public long getLong(long defaultValue) {
+ return getPersistedLong(defaultValue);
+ }
+
+ public boolean putFloat(float value) {
+ return persistFloat(value);
+ }
+
+ public float getFloat(float defaultValue) {
+ return getPersistedFloat(defaultValue);
+ }
+
+ public boolean putBoolean(boolean value) {
+ return persistBoolean(value);
+ }
+
+ public boolean getBoolean(boolean defaultValue) {
+ return getPersistedBoolean(defaultValue);
+ }
+
+ @Override
+ protected void onSetInitialValue(boolean restorePersistedValue, Object defaultValue) {
+ this.mDefaultValue = defaultValue;
+ super.onSetInitialValue(restorePersistedValue, defaultValue);
+ }
+}
diff --git a/v7/recyclerview/src/android/support/v7/util/SortedList.java b/v7/recyclerview/src/android/support/v7/util/SortedList.java
index f96433f..c62d0ce 100644
--- a/v7/recyclerview/src/android/support/v7/util/SortedList.java
+++ b/v7/recyclerview/src/android/support/v7/util/SortedList.java
@@ -361,7 +361,7 @@
* {@link BatchedCallback#dispatchLastEvent()} right after you complete your data changes.
* Failing to do so may create data inconsistencies with the Callback.
* <p>
- * If the current Callback in an instance of {@link BatchedCallback}, calling this method
+ * If the current Callback is an instance of {@link BatchedCallback}, calling this method
* has no effect.
*/
public void beginBatchedUpdates() {