Merge "Add Android specific types to `SavedState` reader and writer" into androidx-main
diff --git a/savedstate/savedstate/api/current.txt b/savedstate/savedstate/api/current.txt
index 3e3d6f9..c1e51e3 100644
--- a/savedstate/savedstate/api/current.txt
+++ b/savedstate/savedstate/api/current.txt
@@ -11,6 +11,8 @@
     method public inline operator boolean contains(String key);
     method public boolean contentDeepEquals(android.os.Bundle other);
     method public int contentDeepHashCode();
+    method public inline android.os.IBinder getBinder(String key);
+    method public inline android.os.IBinder getBinderOrElse(String key, kotlin.jvm.functions.Function0<? extends android.os.IBinder> defaultValue);
     method public inline boolean getBoolean(String key);
     method public inline boolean[] getBooleanArray(String key);
     method public inline boolean[] getBooleanArrayOrElse(String key, kotlin.jvm.functions.Function0<boolean[]> defaultValue);
@@ -19,6 +21,12 @@
     method public inline char[] getCharArray(String key);
     method public inline char[] getCharArrayOrElse(String key, kotlin.jvm.functions.Function0<char[]> defaultValue);
     method public inline char getCharOrElse(String key, kotlin.jvm.functions.Function0<java.lang.Character> defaultValue);
+    method public inline CharSequence getCharSequence(String key);
+    method public inline CharSequence[] getCharSequenceArray(String key);
+    method public inline CharSequence[] getCharSequenceArrayOrElse(String key, kotlin.jvm.functions.Function0<java.lang.CharSequence[]> defaultValue);
+    method public inline java.util.List<java.lang.CharSequence> getCharSequenceList(String key);
+    method public inline java.util.List<java.lang.CharSequence> getCharSequenceListOrElse(String key, kotlin.jvm.functions.Function0<? extends java.util.List<? extends java.lang.CharSequence>> defaultValue);
+    method public inline CharSequence getCharSequenceOrElse(String key, kotlin.jvm.functions.Function0<? extends java.lang.CharSequence> defaultValue);
     method public inline double getDouble(String key);
     method public inline double[] getDoubleArray(String key);
     method public inline double[] getDoubleArrayOrElse(String key, kotlin.jvm.functions.Function0<double[]> defaultValue);
@@ -38,11 +46,21 @@
     method public inline long[] getLongArrayOrElse(String key, kotlin.jvm.functions.Function0<long[]> defaultValue);
     method public inline long getLongOrElse(String key, kotlin.jvm.functions.Function0<java.lang.Long> defaultValue);
     method public inline <reified T extends android.os.Parcelable> T getParcelable(String key);
+    method public inline <reified T extends android.os.Parcelable> T[] getParcelableArray(String key);
+    method public inline <reified T extends android.os.Parcelable> T[] getParcelableArrayOrElse(String key, kotlin.jvm.functions.Function0<T[]> defaultValue);
     method public inline <reified T extends android.os.Parcelable> java.util.List<T> getParcelableList(String key);
     method public inline <reified T extends android.os.Parcelable> java.util.List<T> getParcelableListOrElse(String key, kotlin.jvm.functions.Function0<? extends java.util.List<? extends T>> defaultValue);
     method public inline <reified T extends android.os.Parcelable> T getParcelableOrElse(String key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
     method public inline android.os.Bundle getSavedState(String key);
     method public inline android.os.Bundle getSavedStateOrElse(String key, kotlin.jvm.functions.Function0<android.os.Bundle> defaultValue);
+    method public inline <reified T extends java.io.Serializable> T getSerializable(String key);
+    method public inline <reified T extends java.io.Serializable> T getSerializableOrElse(String key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
+    method public inline android.util.Size getSize(String key);
+    method public inline android.util.SizeF getSizeF(String key);
+    method public inline android.util.SizeF getSizeFOrElse(String key, kotlin.jvm.functions.Function0<android.util.SizeF> defaultValue);
+    method public inline android.util.Size getSizeOrElse(String key, kotlin.jvm.functions.Function0<android.util.Size> defaultValue);
+    method public inline <reified T extends android.os.Parcelable> android.util.SparseArray<T> getSparseParcelableArray(String key);
+    method public inline <reified T extends android.os.Parcelable> android.util.SparseArray<T> getSparseParcelableArrayOrElse(String key, kotlin.jvm.functions.Function0<? extends android.util.SparseArray<T>> defaultValue);
     method public inline String getString(String key);
     method public inline String[] getStringArray(String key);
     method public inline String[] getStringArrayOrElse(String key, kotlin.jvm.functions.Function0<java.lang.String[]> defaultValue);
@@ -95,10 +113,14 @@
   @kotlin.jvm.JvmInline public final value class SavedStateWriter {
     method public inline void clear();
     method public inline void putAll(android.os.Bundle values);
+    method public inline void putBinder(String key, android.os.IBinder value);
     method public inline void putBoolean(String key, boolean value);
     method public inline void putBooleanArray(String key, boolean[] values);
     method public inline void putChar(String key, char value);
     method public inline void putCharArray(String key, char[] values);
+    method public inline void putCharSequence(String key, CharSequence value);
+    method public inline void putCharSequenceArray(String key, CharSequence[] values);
+    method public inline void putCharSequenceList(String key, java.util.List<? extends java.lang.CharSequence> values);
     method public inline void putDouble(String key, double value);
     method public inline void putDoubleArray(String key, double[] values);
     method public inline void putFloat(String key, float value);
@@ -110,8 +132,13 @@
     method public inline void putLongArray(String key, long[] values);
     method public inline void putNull(String key);
     method public inline <reified T extends android.os.Parcelable> void putParcelable(String key, T value);
+    method public inline <reified T extends android.os.Parcelable> void putParcelableArray(String key, T[] values);
     method public inline <reified T extends android.os.Parcelable> void putParcelableList(String key, java.util.List<? extends T> values);
     method public inline void putSavedState(String key, android.os.Bundle value);
+    method public inline <reified T extends java.io.Serializable> void putSerializable(String key, T value);
+    method public inline void putSize(String key, android.util.Size value);
+    method public inline void putSizeF(String key, android.util.SizeF value);
+    method public inline <reified T extends android.os.Parcelable> void putSparseParcelableArray(String key, android.util.SparseArray<T> values);
     method public inline void putString(String key, String value);
     method public inline void putStringArray(String key, String[] values);
     method public inline void putStringList(String key, java.util.List<java.lang.String> values);
diff --git a/savedstate/savedstate/api/restricted_current.txt b/savedstate/savedstate/api/restricted_current.txt
index 94ea74b..eb9ae61 100644
--- a/savedstate/savedstate/api/restricted_current.txt
+++ b/savedstate/savedstate/api/restricted_current.txt
@@ -12,6 +12,8 @@
     method public inline operator boolean contains(String key);
     method public boolean contentDeepEquals(android.os.Bundle other);
     method public int contentDeepHashCode();
+    method public inline android.os.IBinder getBinder(String key);
+    method public inline android.os.IBinder getBinderOrElse(String key, kotlin.jvm.functions.Function0<? extends android.os.IBinder> defaultValue);
     method public inline boolean getBoolean(String key);
     method public inline boolean[] getBooleanArray(String key);
     method public inline boolean[] getBooleanArrayOrElse(String key, kotlin.jvm.functions.Function0<boolean[]> defaultValue);
@@ -20,6 +22,12 @@
     method public inline char[] getCharArray(String key);
     method public inline char[] getCharArrayOrElse(String key, kotlin.jvm.functions.Function0<char[]> defaultValue);
     method public inline char getCharOrElse(String key, kotlin.jvm.functions.Function0<java.lang.Character> defaultValue);
+    method public inline CharSequence getCharSequence(String key);
+    method public inline CharSequence[] getCharSequenceArray(String key);
+    method public inline CharSequence[] getCharSequenceArrayOrElse(String key, kotlin.jvm.functions.Function0<java.lang.CharSequence[]> defaultValue);
+    method public inline java.util.List<java.lang.CharSequence> getCharSequenceList(String key);
+    method public inline java.util.List<java.lang.CharSequence> getCharSequenceListOrElse(String key, kotlin.jvm.functions.Function0<? extends java.util.List<? extends java.lang.CharSequence>> defaultValue);
+    method public inline CharSequence getCharSequenceOrElse(String key, kotlin.jvm.functions.Function0<? extends java.lang.CharSequence> defaultValue);
     method public inline double getDouble(String key);
     method public inline double[] getDoubleArray(String key);
     method public inline double[] getDoubleArrayOrElse(String key, kotlin.jvm.functions.Function0<double[]> defaultValue);
@@ -39,11 +47,21 @@
     method public inline long[] getLongArrayOrElse(String key, kotlin.jvm.functions.Function0<long[]> defaultValue);
     method public inline long getLongOrElse(String key, kotlin.jvm.functions.Function0<java.lang.Long> defaultValue);
     method public inline <reified T extends android.os.Parcelable> T getParcelable(String key);
+    method public inline <reified T extends android.os.Parcelable> T[] getParcelableArray(String key);
+    method public inline <reified T extends android.os.Parcelable> T[] getParcelableArrayOrElse(String key, kotlin.jvm.functions.Function0<T[]> defaultValue);
     method public inline <reified T extends android.os.Parcelable> java.util.List<T> getParcelableList(String key);
     method public inline <reified T extends android.os.Parcelable> java.util.List<T> getParcelableListOrElse(String key, kotlin.jvm.functions.Function0<? extends java.util.List<? extends T>> defaultValue);
     method public inline <reified T extends android.os.Parcelable> T getParcelableOrElse(String key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
     method public inline android.os.Bundle getSavedState(String key);
     method public inline android.os.Bundle getSavedStateOrElse(String key, kotlin.jvm.functions.Function0<android.os.Bundle> defaultValue);
+    method public inline <reified T extends java.io.Serializable> T getSerializable(String key);
+    method public inline <reified T extends java.io.Serializable> T getSerializableOrElse(String key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
+    method public inline android.util.Size getSize(String key);
+    method public inline android.util.SizeF getSizeF(String key);
+    method public inline android.util.SizeF getSizeFOrElse(String key, kotlin.jvm.functions.Function0<android.util.SizeF> defaultValue);
+    method public inline android.util.Size getSizeOrElse(String key, kotlin.jvm.functions.Function0<android.util.Size> defaultValue);
+    method public inline <reified T extends android.os.Parcelable> android.util.SparseArray<T> getSparseParcelableArray(String key);
+    method public inline <reified T extends android.os.Parcelable> android.util.SparseArray<T> getSparseParcelableArrayOrElse(String key, kotlin.jvm.functions.Function0<? extends android.util.SparseArray<T>> defaultValue);
     method public inline String getString(String key);
     method public inline String[] getStringArray(String key);
     method public inline String[] getStringArrayOrElse(String key, kotlin.jvm.functions.Function0<java.lang.String[]> defaultValue);
@@ -115,10 +133,14 @@
     ctor @kotlin.PublishedApi internal SavedStateWriter(@kotlin.PublishedApi android.os.Bundle source);
     method public inline void clear();
     method public inline void putAll(android.os.Bundle values);
+    method public inline void putBinder(String key, android.os.IBinder value);
     method public inline void putBoolean(String key, boolean value);
     method public inline void putBooleanArray(String key, boolean[] values);
     method public inline void putChar(String key, char value);
     method public inline void putCharArray(String key, char[] values);
+    method public inline void putCharSequence(String key, CharSequence value);
+    method public inline void putCharSequenceArray(String key, CharSequence[] values);
+    method public inline void putCharSequenceList(String key, java.util.List<? extends java.lang.CharSequence> values);
     method public inline void putDouble(String key, double value);
     method public inline void putDoubleArray(String key, double[] values);
     method public inline void putFloat(String key, float value);
@@ -130,8 +152,13 @@
     method public inline void putLongArray(String key, long[] values);
     method public inline void putNull(String key);
     method public inline <reified T extends android.os.Parcelable> void putParcelable(String key, T value);
+    method public inline <reified T extends android.os.Parcelable> void putParcelableArray(String key, T[] values);
     method public inline <reified T extends android.os.Parcelable> void putParcelableList(String key, java.util.List<? extends T> values);
     method public inline void putSavedState(String key, android.os.Bundle value);
+    method public inline <reified T extends java.io.Serializable> void putSerializable(String key, T value);
+    method public inline void putSize(String key, android.util.Size value);
+    method public inline void putSizeF(String key, android.util.SizeF value);
+    method public inline <reified T extends android.os.Parcelable> void putSparseParcelableArray(String key, android.util.SparseArray<T> values);
     method public inline void putString(String key, String value);
     method public inline void putStringArray(String key, String[] values);
     method public inline void putStringList(String key, java.util.List<java.lang.String> values);
diff --git a/savedstate/savedstate/bcv/native/current.txt b/savedstate/savedstate/bcv/native/current.txt
index e9f880e..2491285 100644
--- a/savedstate/savedstate/bcv/native/current.txt
+++ b/savedstate/savedstate/bcv/native/current.txt
@@ -66,6 +66,12 @@
     final inline fun getCharArray(kotlin/String): kotlin/CharArray // androidx.savedstate/SavedStateReader.getCharArray|getCharArray(kotlin.String){}[0]
     final inline fun getCharArrayOrElse(kotlin/String, kotlin/Function0<kotlin/CharArray>): kotlin/CharArray // androidx.savedstate/SavedStateReader.getCharArrayOrElse|getCharArrayOrElse(kotlin.String;kotlin.Function0<kotlin.CharArray>){}[0]
     final inline fun getCharOrElse(kotlin/String, kotlin/Function0<kotlin/Char>): kotlin/Char // androidx.savedstate/SavedStateReader.getCharOrElse|getCharOrElse(kotlin.String;kotlin.Function0<kotlin.Char>){}[0]
+    final inline fun getCharSequence(kotlin/String): kotlin/CharSequence // androidx.savedstate/SavedStateReader.getCharSequence|getCharSequence(kotlin.String){}[0]
+    final inline fun getCharSequenceArray(kotlin/String): kotlin/Array<kotlin/CharSequence> // androidx.savedstate/SavedStateReader.getCharSequenceArray|getCharSequenceArray(kotlin.String){}[0]
+    final inline fun getCharSequenceArrayOrElse(kotlin/String, kotlin/Function0<kotlin/Array<kotlin/CharSequence>>): kotlin/Array<kotlin/CharSequence> // androidx.savedstate/SavedStateReader.getCharSequenceArrayOrElse|getCharSequenceArrayOrElse(kotlin.String;kotlin.Function0<kotlin.Array<kotlin.CharSequence>>){}[0]
+    final inline fun getCharSequenceList(kotlin/String): kotlin.collections/List<kotlin/CharSequence> // androidx.savedstate/SavedStateReader.getCharSequenceList|getCharSequenceList(kotlin.String){}[0]
+    final inline fun getCharSequenceListOrElse(kotlin/String, kotlin/Function0<kotlin.collections/List<kotlin/CharSequence>>): kotlin.collections/List<kotlin/CharSequence> // androidx.savedstate/SavedStateReader.getCharSequenceListOrElse|getCharSequenceListOrElse(kotlin.String;kotlin.Function0<kotlin.collections.List<kotlin.CharSequence>>){}[0]
+    final inline fun getCharSequenceOrElse(kotlin/String, kotlin/Function0<kotlin/CharSequence>): kotlin/CharSequence // androidx.savedstate/SavedStateReader.getCharSequenceOrElse|getCharSequenceOrElse(kotlin.String;kotlin.Function0<kotlin.CharSequence>){}[0]
     final inline fun getDouble(kotlin/String): kotlin/Double // androidx.savedstate/SavedStateReader.getDouble|getDouble(kotlin.String){}[0]
     final inline fun getDoubleArray(kotlin/String): kotlin/DoubleArray // androidx.savedstate/SavedStateReader.getDoubleArray|getDoubleArray(kotlin.String){}[0]
     final inline fun getDoubleArrayOrElse(kotlin/String, kotlin/Function0<kotlin/DoubleArray>): kotlin/DoubleArray // androidx.savedstate/SavedStateReader.getDoubleArrayOrElse|getDoubleArrayOrElse(kotlin.String;kotlin.Function0<kotlin.DoubleArray>){}[0]
@@ -112,6 +118,9 @@
     final inline fun putBooleanArray(kotlin/String, kotlin/BooleanArray) // androidx.savedstate/SavedStateWriter.putBooleanArray|putBooleanArray(kotlin.String;kotlin.BooleanArray){}[0]
     final inline fun putChar(kotlin/String, kotlin/Char) // androidx.savedstate/SavedStateWriter.putChar|putChar(kotlin.String;kotlin.Char){}[0]
     final inline fun putCharArray(kotlin/String, kotlin/CharArray) // androidx.savedstate/SavedStateWriter.putCharArray|putCharArray(kotlin.String;kotlin.CharArray){}[0]
+    final inline fun putCharSequence(kotlin/String, kotlin/CharSequence) // androidx.savedstate/SavedStateWriter.putCharSequence|putCharSequence(kotlin.String;kotlin.CharSequence){}[0]
+    final inline fun putCharSequenceArray(kotlin/String, kotlin/Array<kotlin/CharSequence>) // androidx.savedstate/SavedStateWriter.putCharSequenceArray|putCharSequenceArray(kotlin.String;kotlin.Array<kotlin.CharSequence>){}[0]
+    final inline fun putCharSequenceList(kotlin/String, kotlin.collections/List<kotlin/CharSequence>) // androidx.savedstate/SavedStateWriter.putCharSequenceList|putCharSequenceList(kotlin.String;kotlin.collections.List<kotlin.CharSequence>){}[0]
     final inline fun putDouble(kotlin/String, kotlin/Double) // androidx.savedstate/SavedStateWriter.putDouble|putDouble(kotlin.String;kotlin.Double){}[0]
     final inline fun putDoubleArray(kotlin/String, kotlin/DoubleArray) // androidx.savedstate/SavedStateWriter.putDoubleArray|putDoubleArray(kotlin.String;kotlin.DoubleArray){}[0]
     final inline fun putFloat(kotlin/String, kotlin/Float) // androidx.savedstate/SavedStateWriter.putFloat|putFloat(kotlin.String;kotlin.Float){}[0]
diff --git a/savedstate/savedstate/src/androidMain/kotlin/androidx/savedstate/SavedStateReader.android.kt b/savedstate/savedstate/src/androidMain/kotlin/androidx/savedstate/SavedStateReader.android.kt
index b291dac..d3d59e0 100644
--- a/savedstate/savedstate/src/androidMain/kotlin/androidx/savedstate/SavedStateReader.android.kt
+++ b/savedstate/savedstate/src/androidMain/kotlin/androidx/savedstate/SavedStateReader.android.kt
@@ -20,9 +20,17 @@
 
 package androidx.savedstate
 
+import android.os.IBinder
 import android.os.Parcelable
+import android.util.Size
+import android.util.SizeF
+import android.util.SparseArray
 import androidx.core.os.BundleCompat.getParcelable
+import androidx.core.os.BundleCompat.getParcelableArray
 import androidx.core.os.BundleCompat.getParcelableArrayList
+import androidx.core.os.BundleCompat.getSerializable
+import androidx.core.os.BundleCompat.getSparseParcelableArray
+import java.io.Serializable
 
 @JvmInline
 actual value class SavedStateReader
@@ -31,6 +39,33 @@
     @PublishedApi internal actual val source: SavedState,
 ) {
 
+    /**
+     * Retrieves a [IBinder] object associated with the specified key. Throws an
+     * [IllegalStateException] if the key doesn't exist.
+     *
+     * @param key The key to retrieve the value for.
+     * @return The [IBinder] object associated with the key.
+     * @throws IllegalStateException If the key is not found.
+     */
+    inline fun getBinder(key: String): IBinder {
+        if (key !in this) keyNotFoundError(key)
+        return source.getBinder(key) ?: valueNotFoundError(key)
+    }
+
+    /**
+     * Retrieves a [IBinder] object associated with the specified key, or a default value if the key
+     * doesn't exist.
+     *
+     * @param key The key to retrieve the value for.
+     * @param defaultValue A function providing the default [IBinder] if the key is not found.
+     * @return The [IBinder] object associated with the key, or the default value if the key is not
+     *   found.
+     */
+    inline fun getBinderOrElse(key: String, defaultValue: () -> IBinder): IBinder {
+        if (key !in this) defaultValue()
+        return source.getBinder(key) ?: defaultValue()
+    }
+
     actual inline fun getBoolean(key: String): Boolean {
         if (key !in this) keyNotFoundError(key)
         return source.getBoolean(key, DEFAULT_BOOLEAN)
@@ -46,6 +81,19 @@
         return source.getChar(key, DEFAULT_CHAR)
     }
 
+    actual inline fun getCharSequence(key: String): CharSequence {
+        if (key !in this) keyNotFoundError(key)
+        return source.getCharSequence(key) ?: valueNotFoundError(key)
+    }
+
+    actual inline fun getCharSequenceOrElse(
+        key: String,
+        defaultValue: () -> CharSequence
+    ): CharSequence {
+        if (key !in this) defaultValue()
+        return source.getCharSequence(key) ?: defaultValue()
+    }
+
     actual inline fun getCharOrElse(key: String, defaultValue: () -> Char): Char {
         if (key !in this) defaultValue()
         return source.getChar(key, defaultValue())
@@ -118,6 +166,90 @@
         return getParcelable(source, key, T::class.java) ?: defaultValue()
     }
 
+    /**
+     * Retrieves a [Serializable] object associated with the specified key. Throws an
+     * [IllegalStateException] if the key doesn't exist.
+     *
+     * @param key The key to retrieve the value for.
+     * @return The [Serializable] object associated with the key.
+     * @throws IllegalStateException If the key is not found.
+     */
+    inline fun <reified T : Serializable> getSerializable(key: String): T {
+        if (key !in this) keyNotFoundError(key)
+        return getSerializable(source, key, T::class.java) ?: valueNotFoundError(key)
+    }
+
+    /**
+     * Retrieves a [Serializable] object associated with the specified key, or a default value if
+     * the key doesn't exist.
+     *
+     * @param key The key to retrieve the value for.
+     * @param defaultValue A function providing the default [Serializable] if the key is not found.
+     * @return The [Serializable] object associated with the key, or the default value if the key is
+     *   not found.
+     */
+    inline fun <reified T : Serializable> getSerializableOrElse(
+        key: String,
+        defaultValue: () -> T
+    ): T {
+        if (key !in this) defaultValue()
+        return getSerializable(source, key, T::class.java) ?: defaultValue()
+    }
+
+    /**
+     * Retrieves a [Size] object associated with the specified key. Throws an
+     * [IllegalStateException] if the key doesn't exist.
+     *
+     * @param key The key to retrieve the value for.
+     * @return The [Size] object associated with the key.
+     * @throws IllegalStateException If the key is not found.
+     */
+    inline fun getSize(key: String): Size {
+        if (key !in this) keyNotFoundError(key)
+        return source.getSize(key) ?: valueNotFoundError(key)
+    }
+
+    /**
+     * Retrieves a [Size] object associated with the specified key, or a default value if the key
+     * doesn't exist.
+     *
+     * @param key The key to retrieve the value for.
+     * @param defaultValue A function providing the default [Size] if the key is not found.
+     * @return The [Size] object associated with the key, or the default value if the key is not
+     *   found.
+     */
+    inline fun getSizeOrElse(key: String, defaultValue: () -> Size): Size {
+        if (key !in this) defaultValue()
+        return source.getSize(key) ?: defaultValue()
+    }
+
+    /**
+     * Retrieves a [SizeF] object associated with the specified key. Throws an
+     * [IllegalStateException] if the key doesn't exist.
+     *
+     * @param key The key to retrieve the value for.
+     * @return The [SizeF] object associated with the key.
+     * @throws IllegalStateException If the key is not found.
+     */
+    inline fun getSizeF(key: String): SizeF {
+        if (key !in this) keyNotFoundError(key)
+        return source.getSizeF(key) ?: valueNotFoundError(key)
+    }
+
+    /**
+     * Retrieves a [SizeF] object associated with the specified key, or a default value if the key
+     * doesn't exist.
+     *
+     * @param key The key to retrieve the value for.
+     * @param defaultValue A function providing the default [SizeF] if the key is not found.
+     * @return The [SizeF] object associated with the key, or the default value if the key is not
+     *   found.
+     */
+    inline fun getSizeFOrElse(key: String, defaultValue: () -> SizeF): SizeF {
+        if (key !in this) defaultValue()
+        return source.getSizeF(key) ?: defaultValue()
+    }
+
     actual inline fun getString(key: String): String {
         if (key !in this) keyNotFoundError(key)
         return source.getString(key) ?: valueNotFoundError(key)
@@ -138,6 +270,19 @@
         return source.getIntegerArrayList(key) ?: defaultValue()
     }
 
+    actual inline fun getCharSequenceList(key: String): List<CharSequence> {
+        if (key !in this) keyNotFoundError(key)
+        return source.getCharSequenceArrayList(key) ?: valueNotFoundError(key)
+    }
+
+    actual inline fun getCharSequenceListOrElse(
+        key: String,
+        defaultValue: () -> List<CharSequence>
+    ): List<CharSequence> {
+        if (key !in this) defaultValue()
+        return source.getCharSequenceArrayList(key) ?: defaultValue()
+    }
+
     actual inline fun getStringList(key: String): List<String> {
         if (key !in this) keyNotFoundError(key)
         return source.getStringArrayList(key) ?: valueNotFoundError(key)
@@ -170,7 +315,7 @@
      *
      * @param key The [key] to retrieve the value for.
      * @param defaultValue A function providing the default value if the [key] is not found or the
-     *   retrieved value is not a list of [Parcelable].
+     *   retrieved value is not a [List] of [Parcelable].
      * @return The list of elements of [Parcelable] associated with the [key], or the default value
      *   if the [key] is not found.
      */
@@ -205,6 +350,21 @@
         return source.getCharArray(key) ?: defaultValue()
     }
 
+    @Suppress("ArrayReturn")
+    actual inline fun getCharSequenceArray(key: String): Array<CharSequence> {
+        if (key !in this) keyNotFoundError(key)
+        return source.getCharSequenceArray(key) ?: valueNotFoundError(key)
+    }
+
+    @Suppress("ArrayReturn")
+    actual inline fun getCharSequenceArrayOrElse(
+        key: String,
+        defaultValue: () -> Array<CharSequence>
+    ): Array<CharSequence> {
+        if (key !in this) defaultValue()
+        return source.getCharSequenceArray(key) ?: defaultValue()
+    }
+
     actual inline fun getDoubleArray(key: String): DoubleArray {
         if (key !in this) keyNotFoundError(key)
         return source.getDoubleArray(key) ?: valueNotFoundError(key)
@@ -261,6 +421,75 @@
         return source.getStringArray(key) ?: defaultValue()
     }
 
+    /**
+     * Retrieves an [Array] of elements of [Parcelable] associated with the specified [key]. Throws
+     * an [IllegalStateException] if the [key] doesn't exist.
+     *
+     * @param key The [key] to retrieve the value for.
+     * @return The [Array] of elements of [Parcelable] associated with the [key].
+     * @throws IllegalStateException If the [key] is not found.
+     */
+    @Suppress("ArrayReturn")
+    inline fun <reified T : Parcelable> getParcelableArray(key: String): Array<T> {
+        if (key !in this) keyNotFoundError(key)
+        @Suppress("UNCHECKED_CAST")
+        return getParcelableArray(source, key, T::class.java) as? Array<T>
+            ?: valueNotFoundError(key)
+    }
+
+    /**
+     * Retrieves a [Array] of elements of [Parcelable] associated with the specified [key], or a
+     * default value if the [key] doesn't exist.
+     *
+     * @param key The [key] to retrieve the value for.
+     * @param defaultValue A function providing the default value if the [key] is not found or the
+     *   retrieved value is not a [Array] of [Parcelable].
+     * @return The [Array] of elements of [Parcelable] associated with the [key], or the default
+     *   value if the [key] is not found.
+     */
+    @Suppress("ArrayReturn")
+    inline fun <reified T : Parcelable> getParcelableArrayOrElse(
+        key: String,
+        defaultValue: () -> Array<T>
+    ): Array<T> {
+        if (key !in this) defaultValue()
+        @Suppress("UNCHECKED_CAST")
+        return getParcelableArray(source, key, T::class.java) as? Array<T> ?: defaultValue()
+    }
+
+    /**
+     * Retrieves an [SparseArray] of elements of [Parcelable] associated with the specified [key].
+     * Throws an [IllegalStateException] if the [key] doesn't exist.
+     *
+     * @param key The [key] to retrieve the value for.
+     * @return The [SparseArray] of elements of [Parcelable] associated with the [key].
+     * @throws IllegalStateException If the [key] is not found.
+     */
+    inline fun <reified T : Parcelable> getSparseParcelableArray(key: String): SparseArray<T> {
+        if (key !in this) keyNotFoundError(key)
+        return getSparseParcelableArray(source, key, T::class.java) as? SparseArray<T>
+            ?: valueNotFoundError(key)
+    }
+
+    /**
+     * Retrieves a [SparseArray] of elements of [Parcelable] associated with the specified [key], or
+     * a default value if the [key] doesn't exist.
+     *
+     * @param key The [key] to retrieve the value for.
+     * @param defaultValue A function providing the default value if the [key] is not found or the
+     *   retrieved value is not a [SparseArray] of [Parcelable].
+     * @return The [SparseArray] of elements of [Parcelable] associated with the [key], or the
+     *   default value if the [key] is not found.
+     */
+    inline fun <reified T : Parcelable> getSparseParcelableArrayOrElse(
+        key: String,
+        defaultValue: () -> SparseArray<T>
+    ): SparseArray<T> {
+        if (key !in this) defaultValue()
+        return getSparseParcelableArray(source, key, T::class.java) as? SparseArray<T>
+            ?: defaultValue()
+    }
+
     actual inline fun getSavedState(key: String): SavedState {
         if (key !in this) keyNotFoundError(key)
         return source.getBundle(key) ?: valueNotFoundError(key)
diff --git a/savedstate/savedstate/src/androidMain/kotlin/androidx/savedstate/SavedStateWriter.android.kt b/savedstate/savedstate/src/androidMain/kotlin/androidx/savedstate/SavedStateWriter.android.kt
index db7d120..a2795d0 100644
--- a/savedstate/savedstate/src/androidMain/kotlin/androidx/savedstate/SavedStateWriter.android.kt
+++ b/savedstate/savedstate/src/androidMain/kotlin/androidx/savedstate/SavedStateWriter.android.kt
@@ -20,7 +20,12 @@
 
 package androidx.savedstate
 
+import android.os.IBinder
 import android.os.Parcelable
+import android.util.Size
+import android.util.SizeF
+import android.util.SparseArray
+import java.io.Serializable
 
 @JvmInline
 actual value class SavedStateWriter
@@ -29,6 +34,16 @@
     @PublishedApi internal actual val source: SavedState,
 ) {
 
+    /**
+     * Stores an [IBinder] value associated with the specified key in the [IBinder].
+     *
+     * @param key The key to associate the value with.
+     * @param value The [IBinder] value to store.
+     */
+    inline fun putBinder(key: String, value: IBinder) {
+        source.putBinder(key, value)
+    }
+
     actual inline fun putBoolean(key: String, value: Boolean) {
         source.putBoolean(key, value)
     }
@@ -37,6 +52,10 @@
         source.putChar(key, value)
     }
 
+    actual inline fun putCharSequence(key: String, value: CharSequence) {
+        source.putCharSequence(key, value)
+    }
+
     actual inline fun putDouble(key: String, value: Double) {
         source.putDouble(key, value)
     }
@@ -67,6 +86,36 @@
         source.putParcelable(key, value)
     }
 
+    /**
+     * Stores an [Serializable] value associated with the specified key in the [Serializable].
+     *
+     * @param key The key to associate the value with.
+     * @param value The [Serializable] value to store.
+     */
+    inline fun <reified T : Serializable> putSerializable(key: String, value: T) {
+        source.putSerializable(key, value)
+    }
+
+    /**
+     * Stores an [Size] value associated with the specified key in the [Size].
+     *
+     * @param key The key to associate the value with.
+     * @param value The [Size] value to store.
+     */
+    inline fun putSize(key: String, value: Size) {
+        source.putSize(key, value)
+    }
+
+    /**
+     * Stores an [SizeF] value associated with the specified key in the [SizeF].
+     *
+     * @param key The key to associate the value with.
+     * @param value The [SizeF] value to store.
+     */
+    inline fun putSizeF(key: String, value: SizeF) {
+        source.putSizeF(key, value)
+    }
+
     actual inline fun putString(key: String, value: String) {
         source.putString(key, value)
     }
@@ -75,16 +124,20 @@
         source.putIntegerArrayList(key, values.toArrayListUnsafe())
     }
 
+    actual inline fun putCharSequenceList(key: String, values: List<CharSequence>) {
+        source.putCharSequenceArrayList(key, values.toArrayListUnsafe())
+    }
+
     actual inline fun putStringList(key: String, values: List<String>) {
         source.putStringArrayList(key, values.toArrayListUnsafe())
     }
 
     /**
-     * Stores a list of elements of [Parcelable] associated with the specified key in the
+     * Stores a [List] of elements of [Parcelable] associated with the specified key in the
      * [SavedState].
      *
      * @param key The key to associate the value with.
-     * @param values The list of elements to store.
+     * @param values The [List] of elements to store.
      */
     inline fun <reified T : Parcelable> putParcelableList(key: String, values: List<T>) {
         source.putParcelableArrayList(key, values.toArrayListUnsafe())
@@ -98,6 +151,13 @@
         source.putCharArray(key, values)
     }
 
+    actual inline fun putCharSequenceArray(
+        key: String,
+        @Suppress("ArrayReturn") values: Array<CharSequence>
+    ) {
+        source.putCharSequenceArray(key, values)
+    }
+
     actual inline fun putDoubleArray(key: String, values: DoubleArray) {
         source.putDoubleArray(key, values)
     }
@@ -118,6 +178,34 @@
         source.putStringArray(key, values)
     }
 
+    /**
+     * Stores a [Array] of elements of [Parcelable] associated with the specified key in the
+     * [SavedState].
+     *
+     * @param key The key to associate the value with.
+     * @param values The [Array] of elements to store.
+     */
+    inline fun <reified T : Parcelable> putParcelableArray(
+        key: String,
+        @Suppress("ArrayReturn") values: Array<T>
+    ) {
+        source.putParcelableArray(key, values)
+    }
+
+    /**
+     * Stores a [SparseArray] of elements of [Parcelable] associated with the specified key in the
+     * [SavedState].
+     *
+     * @param key The key to associate the value with.
+     * @param values The [SparseArray] of elements to store.
+     */
+    inline fun <reified T : Parcelable> putSparseParcelableArray(
+        key: String,
+        values: SparseArray<T>
+    ) {
+        source.putSparseParcelableArray(key, values)
+    }
+
     actual inline fun putSavedState(key: String, value: SavedState) {
         source.putBundle(key, value)
     }
diff --git a/savedstate/savedstate/src/androidUnitTest/kotlin/androidx/savedstate/ParcelableSavedStateTest.android.kt b/savedstate/savedstate/src/androidUnitTest/kotlin/androidx/savedstate/ParcelableSavedStateTest.android.kt
deleted file mode 100644
index 0a0dd72..0000000
--- a/savedstate/savedstate/src/androidUnitTest/kotlin/androidx/savedstate/ParcelableSavedStateTest.android.kt
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Copyright 2024 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 androidx.savedstate
-
-import android.os.Parcel
-import android.os.Parcelable
-import androidx.kruth.assertThat
-import androidx.kruth.assertThrows
-import kotlin.test.Test
-
-internal class ParcelableSavedStateTest : RobolectricTest() {
-
-    @Test
-    fun getParcelable_whenSet_returns() {
-        val underTest = savedState { putParcelable(KEY_1, PARCELABLE_VALUE_1) }
-        val actual = underTest.read { getParcelable<TestParcelable>(KEY_1) }
-
-        assertThat(actual).isEqualTo(PARCELABLE_VALUE_1)
-    }
-
-    @Test
-    fun getParcelable_whenNotSet_throws() {
-        assertThrows<IllegalArgumentException> {
-            savedState().read { getParcelable<TestParcelable>(KEY_1) }
-        }
-    }
-
-    @Test
-    fun getParcelable_whenSet_differentType_returnsDefault() {
-        val underTest = savedState { putInt(KEY_1, Int.MAX_VALUE) }
-
-        assertThrows<IllegalStateException> {
-            underTest.read { getParcelable<TestParcelable>(KEY_1) }
-        }
-    }
-
-    @Test
-    fun getParcelableOrElse_whenSet_returns() {
-        val underTest = savedState { putParcelable(KEY_1, PARCELABLE_VALUE_1) }
-        val actual = underTest.read { getParcelableOrElse(KEY_1) { PARCELABLE_VALUE_2 } }
-
-        assertThat(actual).isEqualTo(PARCELABLE_VALUE_1)
-    }
-
-    @Test
-    fun getParcelableOrElse_whenNotSet_returnsElse() {
-        val actual = savedState().read { getParcelableOrElse(KEY_1) { PARCELABLE_VALUE_1 } }
-
-        assertThat(actual).isEqualTo(PARCELABLE_VALUE_1)
-    }
-
-    @Test
-    fun getParcelableOrElse_whenSet_differentType_returnsDefault() {
-        val underTest = savedState { putInt(KEY_1, Int.MAX_VALUE) }
-        val actual = underTest.read { getParcelableOrElse(KEY_1) { PARCELABLE_VALUE_1 } }
-
-        assertThat(actual).isEqualTo(PARCELABLE_VALUE_1)
-    }
-
-    @Test
-    fun getParcelableList_whenSet_returns() {
-        val expected = List(size = 5) { idx -> TestParcelable(idx) }
-
-        val underTest = savedState { putParcelableList(KEY_1, expected) }
-        val actual = underTest.read { getParcelableList<TestParcelable>(KEY_1) }
-
-        assertThat(actual).isEqualTo(expected)
-    }
-
-    @Test
-    fun getList_ofParcelable_whenNotSet_throws() {
-        assertThrows<IllegalArgumentException> {
-            savedState().read { getParcelableList<TestParcelable>(KEY_1) }
-        }
-    }
-
-    @Test
-    fun getList_whenSet_differentType_throws() {
-        val underTest = savedState { putInt(KEY_1, Int.MAX_VALUE) }
-
-        assertThrows<IllegalStateException> {
-            underTest.read { getParcelableList<TestParcelable>(KEY_1) }
-        }
-    }
-
-    @Test
-    fun getListOrElse_ofParcelable_whenSet_returns() {
-        val expected = List(size = 5) { idx -> TestParcelable(idx) }
-
-        val underTest = savedState { putParcelableList(KEY_1, expected) }
-        val actual =
-            underTest.read { getParcelableListOrElse<TestParcelable>(KEY_1) { emptyList() } }
-
-        assertThat(actual).isEqualTo(expected)
-    }
-
-    @Test
-    fun getListOrElse_ofParcelable_whenNotSet_returnsElse() {
-        val actual =
-            savedState().read { getParcelableListOrElse<TestParcelable>(KEY_1) { emptyList() } }
-
-        assertThat(actual).isEqualTo(emptyList<TestParcelable>())
-    }
-
-    @Test
-    fun getListOrElse_whenSet_differentType_throws() {
-        val underTest = savedState { putInt(KEY_1, Int.MAX_VALUE) }
-        val actual = underTest.read { getParcelableListOrElse(KEY_1) { emptyList() } }
-
-        assertThat(actual).isEqualTo(emptyList<Parcelable>())
-    }
-
-    private companion object {
-        const val KEY_1 = "KEY_1"
-        val PARCELABLE_VALUE_1 = TestParcelable(value = Int.MIN_VALUE)
-        val PARCELABLE_VALUE_2 = TestParcelable(value = Int.MAX_VALUE)
-    }
-
-    internal data class TestParcelable(val value: Int) : Parcelable {
-
-        override fun describeContents(): Int = 0
-
-        override fun writeToParcel(dest: Parcel, flags: Int) {
-            dest.writeInt(value)
-        }
-
-        companion object {
-            @Suppress("unused")
-            @JvmField
-            val CREATOR =
-                object : Parcelable.Creator<TestParcelable> {
-                    override fun createFromParcel(source: Parcel) =
-                        TestParcelable(value = source.readInt())
-
-                    override fun newArray(size: Int) = arrayOfNulls<TestParcelable>(size)
-                }
-        }
-    }
-}
diff --git a/savedstate/savedstate/src/androidUnitTest/kotlin/androidx/savedstate/SavedStateAndroidTest.android.kt b/savedstate/savedstate/src/androidUnitTest/kotlin/androidx/savedstate/SavedStateAndroidTest.android.kt
new file mode 100644
index 0000000..91f3395
--- /dev/null
+++ b/savedstate/savedstate/src/androidUnitTest/kotlin/androidx/savedstate/SavedStateAndroidTest.android.kt
@@ -0,0 +1,483 @@
+/*
+ * Copyright 2024 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 androidx.savedstate
+
+import android.os.IBinder
+import android.os.Parcel
+import android.os.Parcelable
+import android.util.Size
+import android.util.SizeF
+import android.util.SparseArray
+import androidx.kruth.assertThat
+import androidx.kruth.assertThrows
+import java.io.FileDescriptor
+import java.io.Serializable
+import kotlin.test.Test
+
+internal class ParcelableSavedStateTest : RobolectricTest() {
+
+    @Test
+    fun getBinder_whenSet_returns() {
+        val underTest = savedState { putBinder(KEY_1, BINDER_VALUE_1) }
+        val actual = underTest.read { getBinder(KEY_1) }
+
+        assertThat(actual).isEqualTo(BINDER_VALUE_1)
+    }
+
+    @Test
+    fun getBinder_whenNotSet_throws() {
+        assertThrows<IllegalArgumentException> { savedState().read { getBinder(KEY_1) } }
+    }
+
+    @Test
+    fun getBinder_whenSet_differentType_returnsDefault() {
+        val underTest = savedState { putInt(KEY_1, Int.MAX_VALUE) }
+
+        assertThrows<IllegalStateException> { underTest.read { getBinder(KEY_1) } }
+    }
+
+    @Test
+    fun getBinderOrElse_whenSet_returns() {
+        val underTest = savedState { putBinder(KEY_1, BINDER_VALUE_1) }
+        val actual = underTest.read { getBinderOrElse(KEY_1) { BINDER_VALUE_2 } }
+
+        assertThat(actual).isEqualTo(BINDER_VALUE_1)
+    }
+
+    @Test
+    fun getBinderOrElse_whenNotSet_returnsElse() {
+        val actual = savedState().read { getBinderOrElse(KEY_1) { BINDER_VALUE_2 } }
+
+        assertThat(actual).isEqualTo(BINDER_VALUE_2)
+    }
+
+    @Test
+    fun getBinderOrElse_whenSet_differentType_returnsDefault() {
+        val underTest = savedState { putInt(KEY_1, Int.MAX_VALUE) }
+        val actual = underTest.read { getBinderOrElse(KEY_1) { BINDER_VALUE_2 } }
+
+        assertThat(actual).isEqualTo(BINDER_VALUE_2)
+    }
+
+    @Test
+    fun getSize_whenSet_returns() {
+        val underTest = savedState { putSize(KEY_1, SIZE_IN_PIXEL_VALUE_1) }
+        val actual = underTest.read { getSize(KEY_1) }
+
+        assertThat(actual).isEqualTo(SIZE_IN_PIXEL_VALUE_1)
+    }
+
+    @Test
+    fun getSize_whenNotSet_throws() {
+        assertThrows<IllegalArgumentException> { savedState().read { getSize(KEY_1) } }
+    }
+
+    @Test
+    fun getSize_whenSet_differentType_throws() {
+        val underTest = savedState { putInt(KEY_1, Int.MAX_VALUE) }
+
+        assertThrows<IllegalStateException> { underTest.read { getSize(KEY_1) } }
+    }
+
+    @Test
+    fun getSizeOrElse_whenSet_returns() {
+        val underTest = savedState { putSize(KEY_1, SIZE_IN_PIXEL_VALUE_1) }
+        val actual = underTest.read { getSizeOrElse(KEY_1) { SIZE_IN_PIXEL_VALUE_2 } }
+
+        assertThat(actual).isEqualTo(SIZE_IN_PIXEL_VALUE_1)
+    }
+
+    @Test
+    fun getSizeOrElse_whenNotSet_returnsElse() {
+        val actual = savedState().read { getSizeOrElse(KEY_1) { SIZE_IN_PIXEL_VALUE_2 } }
+
+        assertThat(actual).isEqualTo(SIZE_IN_PIXEL_VALUE_2)
+    }
+
+    @Test
+    fun getSizeOrElse_whenSet_differentType_returnsDefault() {
+        val underTest = savedState { putInt(KEY_1, Int.MAX_VALUE) }
+        val actual = underTest.read { getSizeOrElse(KEY_1) { SIZE_IN_PIXEL_VALUE_2 } }
+
+        assertThat(actual).isEqualTo(SIZE_IN_PIXEL_VALUE_2)
+    }
+
+    @Test
+    fun getSizeF_whenSet_returns() {
+        val underTest = savedState { putSizeF(KEY_1, SIZE_IN_FLOAT_VALUE_1) }
+        val actual = underTest.read { getSizeF(KEY_1) }
+
+        assertThat(actual).isEqualTo(SIZE_IN_FLOAT_VALUE_1)
+    }
+
+    @Test
+    fun getSizeF_whenNotSet_throws() {
+        assertThrows<IllegalArgumentException> { savedState().read { getSizeF(KEY_1) } }
+    }
+
+    @Test
+    fun getSizeF_whenSet_differentType_throws() {
+        val underTest = savedState { putInt(KEY_1, Int.MAX_VALUE) }
+
+        assertThrows<IllegalStateException> { underTest.read { getSizeF(KEY_1) } }
+    }
+
+    @Test
+    fun getSizeFOrElse_whenSet_returns() {
+        val underTest = savedState { putSizeF(KEY_1, SIZE_IN_FLOAT_VALUE_1) }
+        val actual = underTest.read { getSizeFOrElse(KEY_1) { SIZE_IN_FLOAT_VALUE_2 } }
+
+        assertThat(actual).isEqualTo(SIZE_IN_FLOAT_VALUE_1)
+    }
+
+    @Test
+    fun getSizeFOrElse_whenNotSet_returnsElse() {
+        val actual = savedState().read { getSizeFOrElse(KEY_1) { SIZE_IN_FLOAT_VALUE_2 } }
+
+        assertThat(actual).isEqualTo(SIZE_IN_FLOAT_VALUE_2)
+    }
+
+    @Test
+    fun getSizeFOrElse_whenSet_differentType_returnsDefault() {
+        val underTest = savedState { putInt(KEY_1, Int.MAX_VALUE) }
+        val actual = underTest.read { getSizeFOrElse(KEY_1) { SIZE_IN_FLOAT_VALUE_2 } }
+
+        assertThat(actual).isEqualTo(SIZE_IN_FLOAT_VALUE_2)
+    }
+
+    @Test
+    fun getParcelable_whenSet_returns() {
+        val underTest = savedState { putParcelable(KEY_1, PARCELABLE_VALUE_1) }
+        val actual = underTest.read { getParcelable<TestParcelable>(KEY_1) }
+
+        assertThat(actual).isEqualTo(PARCELABLE_VALUE_1)
+    }
+
+    @Test
+    fun getParcelable_whenNotSet_throws() {
+        assertThrows<IllegalArgumentException> {
+            savedState().read { getParcelable<TestParcelable>(KEY_1) }
+        }
+    }
+
+    @Test
+    fun getParcelable_whenSet_differentType_throws() {
+        val underTest = savedState { putInt(KEY_1, Int.MAX_VALUE) }
+
+        assertThrows<IllegalStateException> {
+            underTest.read { getParcelable<TestParcelable>(KEY_1) }
+        }
+    }
+
+    @Test
+    fun getParcelableOrElse_whenSet_returns() {
+        val underTest = savedState { putParcelable(KEY_1, PARCELABLE_VALUE_1) }
+        val actual = underTest.read { getParcelableOrElse(KEY_1) { PARCELABLE_VALUE_2 } }
+
+        assertThat(actual).isEqualTo(PARCELABLE_VALUE_1)
+    }
+
+    @Test
+    fun getParcelableOrElse_whenNotSet_returnsElse() {
+        val actual = savedState().read { getParcelableOrElse(KEY_1) { PARCELABLE_VALUE_1 } }
+
+        assertThat(actual).isEqualTo(PARCELABLE_VALUE_1)
+    }
+
+    @Test
+    fun getParcelableOrElse_whenSet_differentType_returnsDefault() {
+        val underTest = savedState { putInt(KEY_1, Int.MAX_VALUE) }
+        val actual = underTest.read { getParcelableOrElse(KEY_1) { PARCELABLE_VALUE_1 } }
+
+        assertThat(actual).isEqualTo(PARCELABLE_VALUE_1)
+    }
+
+    @Test
+    fun getParcelableList_whenSet_returns() {
+        val expected = List(size = 5) { idx -> TestParcelable(idx) }
+
+        val underTest = savedState { putParcelableList(KEY_1, expected) }
+        val actual = underTest.read { getParcelableList<TestParcelable>(KEY_1) }
+
+        assertThat(actual).isEqualTo(expected)
+    }
+
+    @Test
+    fun getParcelableList_whenNotSet_throws() {
+        assertThrows<IllegalArgumentException> {
+            savedState().read { getParcelableList<TestParcelable>(KEY_1) }
+        }
+    }
+
+    @Test
+    fun getParcelableList_whenSet_differentType_throws() {
+        val underTest = savedState { putInt(KEY_1, Int.MAX_VALUE) }
+
+        assertThrows<IllegalStateException> {
+            underTest.read { getParcelableList<TestParcelable>(KEY_1) }
+        }
+    }
+
+    @Test
+    fun getParcelableListOrElse_whenSet_returns() {
+        val expected = List(size = 5) { idx -> TestParcelable(idx) }
+
+        val underTest = savedState { putParcelableList(KEY_1, expected) }
+        val actual =
+            underTest.read { getParcelableListOrElse<TestParcelable>(KEY_1) { emptyList() } }
+
+        assertThat(actual).isEqualTo(expected)
+    }
+
+    @Test
+    fun getParcelableListOrElse_whenNotSet_returnsElse() {
+        val actual =
+            savedState().read { getParcelableListOrElse<TestParcelable>(KEY_1) { emptyList() } }
+
+        assertThat(actual).isEqualTo(emptyList<TestParcelable>())
+    }
+
+    @Test
+    fun getParcelableListOrElse_whenSet_differentType_throws() {
+        val underTest = savedState { putInt(KEY_1, Int.MAX_VALUE) }
+        val actual = underTest.read { getParcelableListOrElse(KEY_1) { emptyList() } }
+
+        assertThat(actual).isEqualTo(emptyList<Parcelable>())
+    }
+
+    @Test
+    fun getParcelableArray_whenSet_returns() {
+        val expected = Array(size = 5) { idx -> TestParcelable(idx) }
+
+        val underTest = savedState { putParcelableArray(KEY_1, expected) }
+        val actual = underTest.read { getParcelableArray<TestParcelable>(KEY_1) }
+
+        assertThat(actual).isEqualTo(expected)
+    }
+
+    @Test
+    fun getParcelableArray_ofParcelable_whenNotSet_throws() {
+        assertThrows<IllegalArgumentException> {
+            savedState().read { getParcelableArray<TestParcelable>(KEY_1) }
+        }
+    }
+
+    @Test
+    fun getParcelableArray_whenSet_differentType_throws() {
+        val underTest = savedState { putInt(KEY_1, Int.MAX_VALUE) }
+
+        assertThrows<IllegalStateException> {
+            underTest.read { getParcelableArray<TestParcelable>(KEY_1) }
+        }
+    }
+
+    @Test
+    fun getParcelableArrayOrElse_whenSet_returns() {
+        val expected = Array(size = 5) { idx -> TestParcelable(idx) }
+
+        val underTest = savedState { putParcelableArray(KEY_1, expected) }
+        val actual =
+            underTest.read { getParcelableArrayOrElse<TestParcelable>(KEY_1) { emptyArray() } }
+
+        assertThat(actual).isEqualTo(expected)
+    }
+
+    @Test
+    fun getParcelableArrayOrElse_ofParcelable_whenNotSet_returnsElse() {
+        val actual =
+            savedState().read { getParcelableArrayOrElse<TestParcelable>(KEY_1) { emptyArray() } }
+
+        assertThat(actual).isEqualTo(emptyArray<TestParcelable>())
+    }
+
+    @Test
+    fun getParcelableArrayOrElse_whenSet_differentType_throws() {
+        val underTest = savedState { putInt(KEY_1, Int.MAX_VALUE) }
+        val actual = underTest.read { getParcelableArrayOrElse(KEY_1) { emptyArray() } }
+
+        assertThat(actual).isEqualTo(emptyArray<Parcelable>())
+    }
+
+    @Test
+    fun getSparseParcelableArray_whenSet_returns() {
+        val expected = SPARSE_PARCELABLE_ARRAY
+
+        val underTest = savedState { putSparseParcelableArray(KEY_1, expected) }
+        val actual = underTest.read { getSparseParcelableArray<TestParcelable>(KEY_1) }
+
+        assertThat(actual).isEqualTo(expected)
+    }
+
+    @Test
+    fun getSparseParcelableArray_ofParcelable_whenNotSet_throws() {
+        assertThrows<IllegalArgumentException> {
+            savedState().read { getSparseParcelableArray<TestParcelable>(KEY_1) }
+        }
+    }
+
+    @Test
+    fun getSparseParcelableArray_whenSet_differentType_throws() {
+        val underTest = savedState { putInt(KEY_1, Int.MAX_VALUE) }
+
+        assertThrows<IllegalStateException> {
+            underTest.read { getSparseParcelableArray<TestParcelable>(KEY_1) }
+        }
+    }
+
+    @Test
+    fun getSparseParcelableArrayOrElse_whenSet_returns() {
+        val expected = SPARSE_PARCELABLE_ARRAY
+
+        val underTest = savedState { putSparseParcelableArray(KEY_1, expected) }
+        val actual =
+            underTest.read {
+                getSparseParcelableArrayOrElse<TestParcelable>(KEY_1) { SparseArray() }
+            }
+
+        assertThat(actual).isEqualTo(expected)
+    }
+
+    @Test
+    fun getSparseParcelableArrayOrElse_ofParcelable_whenNotSet_returnsElse() {
+        val expected = SPARSE_PARCELABLE_ARRAY
+
+        val actual =
+            savedState().read { getSparseParcelableArrayOrElse<TestParcelable>(KEY_1) { expected } }
+
+        assertThat(actual).isEqualTo(expected)
+    }
+
+    @Test
+    fun getSparseParcelableArrayOrElse_whenSet_differentType_throws() {
+        val expected = SPARSE_PARCELABLE_ARRAY
+
+        val underTest = savedState { putInt(KEY_1, Int.MAX_VALUE) }
+        val actual = underTest.read { getSparseParcelableArrayOrElse(KEY_1) { expected } }
+
+        assertThat(actual).isEqualTo(expected)
+    }
+
+    @Test
+    fun getSerializable_whenSet_returns() {
+        val underTest = savedState { putSerializable(KEY_1, SERIALIZABLE_VALUE_1) }
+        val actual = underTest.read { getSerializable<TestSerializable>(KEY_1) }
+
+        assertThat(actual).isEqualTo(SERIALIZABLE_VALUE_1)
+    }
+
+    @Test
+    fun getSerializable_whenNotSet_throws() {
+        assertThrows<IllegalArgumentException> {
+            savedState().read { getSerializable<TestSerializable>(KEY_1) }
+        }
+    }
+
+    @Test
+    fun getSerializable_whenSet_differentType_throws() {
+        val underTest = savedState { putInt(KEY_1, Int.MAX_VALUE) }
+
+        assertThrows<IllegalStateException> {
+            underTest.read { getSerializable<TestSerializable>(KEY_1) }
+        }
+    }
+
+    @Test
+    fun getSerializableOrElse_whenSet_returns() {
+        val underTest = savedState { putSerializable(KEY_1, SERIALIZABLE_VALUE_1) }
+        val actual = underTest.read { getSerializableOrElse(KEY_1) { SERIALIZABLE_VALUE_2 } }
+
+        assertThat(actual).isEqualTo(SERIALIZABLE_VALUE_1)
+    }
+
+    @Test
+    fun getSerializableOrElse_whenNotSet_returnsElse() {
+        val actual = savedState().read { getSerializableOrElse(KEY_1) { SERIALIZABLE_VALUE_2 } }
+
+        assertThat(actual).isEqualTo(SERIALIZABLE_VALUE_2)
+    }
+
+    @Test
+    fun getSerializableOrElse_whenSet_differentType_returnsDefault() {
+        val underTest = savedState { putInt(KEY_1, Int.MAX_VALUE) }
+        val actual = underTest.read { getSerializableOrElse(KEY_1) { SERIALIZABLE_VALUE_1 } }
+
+        assertThat(actual).isEqualTo(SERIALIZABLE_VALUE_1)
+    }
+
+    private companion object {
+        const val KEY_1 = "KEY_1"
+        val SIZE_IN_PIXEL_VALUE_1 = Size(/* width= */ Int.MIN_VALUE, /* height */ Int.MIN_VALUE)
+        val SIZE_IN_PIXEL_VALUE_2 = Size(/* width= */ Int.MAX_VALUE, /* height */ Int.MAX_VALUE)
+        val SIZE_IN_FLOAT_VALUE_1 =
+            SizeF(/* width= */ Float.MIN_VALUE, /* height */ Float.MIN_VALUE)
+        val SIZE_IN_FLOAT_VALUE_2 =
+            SizeF(/* width= */ Float.MAX_VALUE, /* height */ Float.MAX_VALUE)
+        val BINDER_VALUE_1 = TestBinder(value = Int.MIN_VALUE)
+        val BINDER_VALUE_2 = TestBinder(value = Int.MAX_VALUE)
+        val PARCELABLE_VALUE_1 = TestParcelable(value = Int.MIN_VALUE)
+        val PARCELABLE_VALUE_2 = TestParcelable(value = Int.MAX_VALUE)
+        val SERIALIZABLE_VALUE_1 = TestSerializable(value = Int.MIN_VALUE)
+        val SERIALIZABLE_VALUE_2 = TestSerializable(value = Int.MAX_VALUE)
+        val SPARSE_PARCELABLE_ARRAY =
+            SparseArray<TestParcelable>(/* initialCapacity= */ 5).apply {
+                repeat(times = 5) { idx -> put(idx, TestParcelable(idx)) }
+            }
+    }
+
+    internal data class TestBinder(val value: Int) : IBinder {
+        override fun getInterfaceDescriptor() = error("")
+
+        override fun pingBinder() = error("")
+
+        override fun isBinderAlive() = error("")
+
+        override fun queryLocalInterface(descriptor: String) = error("")
+
+        override fun dump(fd: FileDescriptor, args: Array<out String>?) = error("")
+
+        override fun dumpAsync(fd: FileDescriptor, args: Array<out String>?) = error("")
+
+        override fun transact(code: Int, data: Parcel, reply: Parcel?, flags: Int) = error("")
+
+        override fun linkToDeath(recipient: IBinder.DeathRecipient, flags: Int) = error("")
+
+        override fun unlinkToDeath(recipient: IBinder.DeathRecipient, flags: Int) = error("")
+    }
+
+    internal data class TestParcelable(val value: Int) : Parcelable {
+
+        override fun describeContents(): Int = 0
+
+        override fun writeToParcel(dest: Parcel, flags: Int) {
+            dest.writeInt(value)
+        }
+
+        companion object {
+            @Suppress("unused")
+            @JvmField
+            val CREATOR =
+                object : Parcelable.Creator<TestParcelable> {
+                    override fun createFromParcel(source: Parcel) =
+                        TestParcelable(value = source.readInt())
+
+                    override fun newArray(size: Int) = arrayOfNulls<TestParcelable>(size)
+                }
+        }
+    }
+
+    internal data class TestSerializable(val value: Int) : Serializable
+}
diff --git a/savedstate/savedstate/src/commonMain/kotlin/androidx/savedstate/SavedStateReader.kt b/savedstate/savedstate/src/commonMain/kotlin/androidx/savedstate/SavedStateReader.kt
index 5249fa0..a18e93e 100644
--- a/savedstate/savedstate/src/commonMain/kotlin/androidx/savedstate/SavedStateReader.kt
+++ b/savedstate/savedstate/src/commonMain/kotlin/androidx/savedstate/SavedStateReader.kt
@@ -25,10 +25,15 @@
 import kotlin.jvm.JvmName
 
 @PublishedApi internal const val DEFAULT_BOOLEAN: Boolean = false
+
 @PublishedApi internal const val DEFAULT_CHAR: Char = 0.toChar()
+
 @PublishedApi internal const val DEFAULT_FLOAT: Float = 0F
+
 @PublishedApi internal const val DEFAULT_DOUBLE: Double = 0.0
+
 @PublishedApi internal const val DEFAULT_INT: Int = 0
+
 @PublishedApi internal const val DEFAULT_LONG: Long = 0L
 
 /**
@@ -87,6 +92,30 @@
     public inline fun getCharOrElse(key: String, defaultValue: () -> Char): Char
 
     /**
+     * Retrieves a [CharSequence] value associated with the specified [key]. Throws an
+     * [IllegalStateException] if the [key] doesn't exist.
+     *
+     * @param key The [key] to retrieve the value for.
+     * @return The [CharSequence] value associated with the [key].
+     * @throws IllegalStateException If the [key] is not found.
+     */
+    public inline fun getCharSequence(key: String): CharSequence
+
+    /**
+     * Retrieves a [CharSequence] value associated with the specified [key], or a default value if
+     * the [key] doesn't exist.
+     *
+     * @param key The [key] to retrieve the value for.
+     * @param defaultValue A function providing the default value if the [key] is not found.
+     * @return The [CharSequence] value associated with the [key], or the default value if the [key]
+     *   is not found.
+     */
+    public inline fun getCharSequenceOrElse(
+        key: String,
+        defaultValue: () -> CharSequence
+    ): CharSequence
+
+    /**
      * Retrieves a [Double] value associated with the specified [key]. Throws an
      * [IllegalStateException] if the [key] doesn't exist.
      *
@@ -239,6 +268,31 @@
     ): List<String>
 
     /**
+     * Retrieves a [List] of elements of [CharArray] associated with the specified [key]. Throws an
+     * [IllegalStateException] if the [key] doesn't exist.
+     *
+     * @param key The [key] to retrieve the value for.
+     * @return The [List] of elements of [CharArray] associated with the [key].
+     * @throws IllegalStateException If the [key] is not found.
+     */
+    public inline fun getCharSequenceList(key: String): List<CharSequence>
+
+    /**
+     * Retrieves a [List] of elements of [CharSequence] associated with the specified [key], or a
+     * default value if the [key] doesn't exist.
+     *
+     * @param key The [key] to retrieve the value for.
+     * @param defaultValue A function providing the default value if the [key] is not found or the
+     *   retrieved value is not a list of [CharSequence].
+     * @return The list of elements of [CharSequence] associated with the [key], or the default
+     *   value if the [key] is not found.
+     */
+    public inline fun getCharSequenceListOrElse(
+        key: String,
+        defaultValue: () -> List<CharSequence>
+    ): List<CharSequence>
+
+    /**
      * Retrieves a [BooleanArray] value associated with the specified [key]. Throws an
      * [IllegalStateException] if the [key] doesn't exist.
      *
@@ -284,6 +338,30 @@
     public inline fun getCharArrayOrElse(key: String, defaultValue: () -> CharArray): CharArray
 
     /**
+     * Retrieves a [CharArray] value associated with the specified [key]. Throws an
+     * [IllegalStateException] if the [key] doesn't exist.
+     *
+     * @param key The [key] to retrieve the value for.
+     * @return The [CharArray] value associated with the [key].
+     * @throws IllegalStateException If the [key] is not found.
+     */
+    public inline fun getCharSequenceArray(key: String): Array<CharSequence>
+
+    /**
+     * Retrieves a [CharArray] value associated with the specified [key], or a default value if the
+     * [key] doesn't exist.
+     *
+     * @param key The [key] to retrieve the value for.
+     * @param defaultValue A function providing the default value if the [key] is not found.
+     * @return The [CharArray] value associated with the [key], or the default value if the [key] is
+     *   not found.
+     */
+    public inline fun getCharSequenceArrayOrElse(
+        key: String,
+        defaultValue: () -> Array<CharSequence>
+    ): Array<CharSequence>
+
+    /**
      * Retrieves a [DoubleArray] value associated with the specified [key]. Throws an
      * [IllegalStateException] if the [key] doesn't exist.
      *
diff --git a/savedstate/savedstate/src/commonMain/kotlin/androidx/savedstate/SavedStateWriter.kt b/savedstate/savedstate/src/commonMain/kotlin/androidx/savedstate/SavedStateWriter.kt
index 13b5c8f..11cd15c04 100644
--- a/savedstate/savedstate/src/commonMain/kotlin/androidx/savedstate/SavedStateWriter.kt
+++ b/savedstate/savedstate/src/commonMain/kotlin/androidx/savedstate/SavedStateWriter.kt
@@ -45,9 +45,23 @@
      */
     public inline fun putBoolean(key: String, value: Boolean)
 
+    /**
+     * Stores a char value associated with the specified key in the [SavedState].
+     *
+     * @param key The key to associate the value with.
+     * @param value The char value to store.
+     */
     public inline fun putChar(key: String, value: Char)
 
     /**
+     * Stores a char sequence value associated with the specified key in the [SavedState].
+     *
+     * @param key The key to associate the value with.
+     * @param value The char sequence value to store.
+     */
+    public inline fun putCharSequence(key: String, value: CharSequence)
+
+    /**
      * Stores a double value associated with the specified key in the [SavedState].
      *
      * @param key The key to associate the value with.
@@ -103,6 +117,15 @@
     public inline fun putIntList(key: String, values: List<Int>)
 
     /**
+     * Stores a list of elements of [CharSequence] associated with the specified key in the
+     * [SavedState].
+     *
+     * @param key The key to associate the value with.
+     * @param values The list of elements to store.
+     */
+    public inline fun putCharSequenceList(key: String, values: List<CharSequence>)
+
+    /**
      * Stores a list of elements of [String] associated with the specified key in the [SavedState].
      *
      * @param key The key to associate the value with.
@@ -129,6 +152,15 @@
     public inline fun putCharArray(key: String, values: CharArray)
 
     /**
+     * Stores an [Array] of elements of [CharSequence] associated with the specified key in the
+     * [SavedState].
+     *
+     * @param key The key to associate the value with.
+     * @param values The array of elements to store.
+     */
+    public inline fun putCharSequenceArray(key: String, values: Array<CharSequence>)
+
+    /**
      * Stores an [Array] of elements of [Double] associated with the specified key in the
      * [SavedState].
      *
diff --git a/savedstate/savedstate/src/commonTest/kotlin/androidx/savedstate/SavedStateTest.kt b/savedstate/savedstate/src/commonTest/kotlin/androidx/savedstate/SavedStateTest.kt
index fc57a73..d19506c 100644
--- a/savedstate/savedstate/src/commonTest/kotlin/androidx/savedstate/SavedStateTest.kt
+++ b/savedstate/savedstate/src/commonTest/kotlin/androidx/savedstate/SavedStateTest.kt
@@ -332,6 +332,49 @@
     }
 
     @Test
+    fun getCharSequence_whenSet_returns() {
+        val underTest = savedState { putCharSequence(KEY_1, CHAR_SEQUENCE_VALUE_1) }
+        val actual = underTest.read { getCharSequence(KEY_1) }
+
+        assertThat(actual).isEqualTo(CHAR_SEQUENCE_VALUE_1)
+    }
+
+    @Test
+    fun getCharSequence_whenNotSet_throws() {
+        assertThrows<IllegalArgumentException> { savedState().read { getCharSequence(KEY_1) } }
+    }
+
+    @Test
+    fun getCharSequence_whenSet_differentType_throws() {
+        val underTest = savedState { putInt(KEY_1, Int.MAX_VALUE) }
+
+        assertThrows<IllegalStateException> { underTest.read { getString(KEY_1) } }
+    }
+
+    @Test
+    fun getCharSequenceOrElse_whenSet_returns() {
+        val underTest = savedState { putCharSequence(KEY_1, CHAR_SEQUENCE_VALUE_1) }
+        val actual = underTest.read { getCharSequenceOrElse(KEY_1) { CHAR_SEQUENCE_VALUE_2 } }
+
+        assertThat(actual).isEqualTo(CHAR_SEQUENCE_VALUE_1)
+    }
+
+    @Test
+    fun getCharSequenceOrElse_whenNotSet_returnsElse() {
+        val actual = savedState().read { getCharSequenceOrElse(KEY_1) { CHAR_SEQUENCE_VALUE_2 } }
+
+        assertThat(actual).isEqualTo(CHAR_SEQUENCE_VALUE_2)
+    }
+
+    @Test
+    fun getCharSequenceOrElse_whenSet_differentType_returnsElse() {
+        val underTest = savedState { putInt(KEY_1, Int.MAX_VALUE) }
+        val actual = underTest.read { getCharSequenceOrElse(KEY_1) { CHAR_SEQUENCE_VALUE_2 } }
+
+        assertThat(actual).isEqualTo(CHAR_SEQUENCE_VALUE_2)
+    }
+
+    @Test
     fun getDouble_whenSet_returns() {
         val underTest = savedState { putDouble(KEY_1, Double.MAX_VALUE) }
         val actual = underTest.read { getDouble(KEY_1) }
@@ -625,6 +668,53 @@
     }
 
     @Test
+    fun getCharSequenceList_whenSet_returns() {
+        val underTest = savedState { putCharSequenceList(KEY_1, CHAR_SEQUENCE_LIST) }
+        val actual = underTest.read { getCharSequenceList(KEY_1) }
+
+        assertThat(actual).isEqualTo(CHAR_SEQUENCE_LIST)
+    }
+
+    @Test
+    fun getCharSequenceList_whenNotSet_throws() {
+        assertThrows<IllegalArgumentException> { savedState().read { getCharSequenceList(KEY_1) } }
+    }
+
+    @Test
+    fun getCharSequenceList_whenSet_differentType_throws() {
+        val expected = Int.MAX_VALUE
+
+        val underTest = savedState { putInt(KEY_1, expected) }
+
+        assertThrows<IllegalStateException> { underTest.read { getCharSequenceList(KEY_1) } }
+    }
+
+    @Test
+    fun getCharSequenceListOrElse_whenSet_returns() {
+        val underTest = savedState { putCharSequenceList(KEY_1, CHAR_SEQUENCE_LIST) }
+        val actual = underTest.read { getCharSequenceListOrElse(KEY_1) { emptyList() } }
+
+        assertThat(actual).isEqualTo(CHAR_SEQUENCE_LIST)
+    }
+
+    @Test
+    fun getCharSequenceListOrElse_whenNotSet_returnsElse() {
+        val actual = savedState().read { getCharSequenceListOrElse(KEY_1) { emptyList() } }
+
+        assertThat(actual).isEqualTo(emptyList<CharSequence>())
+    }
+
+    @Test
+    fun getCharSequenceListOrElse_whenSet_differentType_returnsElse() {
+        val expected = Int.MAX_VALUE
+
+        val underTest = savedState { putInt(KEY_1, expected) }
+        val actual = underTest.read { getCharSequenceListOrElse(KEY_1) { emptyList() } }
+
+        assertThat(actual).isEqualTo(emptyList<CharSequence>())
+    }
+
+    @Test
     fun getStringList_whenSet_returns() {
         val underTest = savedState { putStringList(KEY_1, LIST_STRING_VALUE) }
         val actual = underTest.read { getStringList(KEY_1) }
@@ -778,6 +868,59 @@
     }
 
     @Test
+    fun getCharSequenceArray_whenSet_returns() {
+        val expected = Array<CharSequence>(size = 5) { idx -> idx.toString() }
+
+        val underTest = savedState { putCharSequenceArray(KEY_1, expected) }
+        val actual = underTest.read { getCharSequenceArray(KEY_1) }
+
+        assertThat(actual).isEqualTo(expected)
+    }
+
+    @Test
+    fun getCharSequenceArray_whenNotSet_throws() {
+        assertThrows<IllegalArgumentException> { savedState().read { getCharSequenceArray(KEY_1) } }
+    }
+
+    @Test
+    fun getCharSequenceArray_whenSet_differentType_throws() {
+        val expected = Int.MAX_VALUE
+
+        val underTest = savedState { putInt(KEY_1, expected) }
+
+        assertThrows<IllegalStateException> { underTest.read { getCharSequenceArray(KEY_1) } }
+    }
+
+    @Test
+    fun getCharSequenceArrayOrElse_whenSet_returns() {
+        val expected = CHAR_SEQUENCE_ARRAY
+
+        val underTest = savedState { putCharSequenceArray(KEY_1, expected) }
+        val actual = underTest.read { getCharSequenceArrayOrElse(KEY_1) { emptyArray() } }
+
+        assertThat(actual).isEqualTo(expected)
+    }
+
+    @Test
+    fun getCharSequenceArrayOrElse_whenNotSet_returnsElse() {
+        val expected = CHAR_SEQUENCE_ARRAY
+
+        val actual = savedState().read { getCharSequenceArrayOrElse(KEY_1) { expected } }
+
+        assertThat(actual).isEqualTo(expected)
+    }
+
+    @Test
+    fun getCharSequenceArrayOrElse_whenSet_differentType_returnsElse() {
+        val expected = CHAR_SEQUENCE_ARRAY
+
+        val underTest = savedState { putInt(KEY_1, Int.MAX_VALUE) }
+        val actual = underTest.read { getCharSequenceArrayOrElse(KEY_1) { expected } }
+
+        assertThat(actual).isEqualTo(expected)
+    }
+
+    @Test
     fun getDoubleArray_whenSet_returns() {
         val expected = DoubleArray(size = 5) { idx -> idx.toDouble() }
 
@@ -1109,6 +1252,10 @@
         val LIST_INT_VALUE = List(size = 5) { idx -> idx }
         val LIST_STRING_VALUE = List(size = 5) { idx -> "index=$idx" }
         val SAVED_STATE_VALUE = savedState()
+        val CHAR_SEQUENCE_VALUE_1: CharSequence = Int.MIN_VALUE.toString()
+        val CHAR_SEQUENCE_VALUE_2: CharSequence = Int.MAX_VALUE.toString()
+        val CHAR_SEQUENCE_ARRAY = Array<CharSequence>(size = 5) { idx -> "index=$idx" }
+        val CHAR_SEQUENCE_LIST = List<CharSequence>(size = 5) { idx -> "index=$idx" }
 
         private fun createDefaultSavedState(): SavedState {
             var key = 0
diff --git a/savedstate/savedstate/src/nonAndroidMain/kotlin/androidx/savedstate/SavedStateReader.nonAndroid.kt b/savedstate/savedstate/src/nonAndroidMain/kotlin/androidx/savedstate/SavedStateReader.nonAndroid.kt
index 5a36f36..b18561a 100644
--- a/savedstate/savedstate/src/nonAndroidMain/kotlin/androidx/savedstate/SavedStateReader.nonAndroid.kt
+++ b/savedstate/savedstate/src/nonAndroidMain/kotlin/androidx/savedstate/SavedStateReader.nonAndroid.kt
@@ -51,6 +51,19 @@
         return source.map[key] as? Char ?: defaultValue()
     }
 
+    actual inline fun getCharSequence(key: String): CharSequence {
+        if (key !in this) keyNotFoundError(key)
+        return source.map[key] as? CharSequence ?: valueNotFoundError(key)
+    }
+
+    actual inline fun getCharSequenceOrElse(
+        key: String,
+        defaultValue: () -> CharSequence
+    ): CharSequence {
+        if (key !in this) defaultValue()
+        return source.map[key] as? CharSequence ?: defaultValue()
+    }
+
     actual inline fun getDouble(key: String): Double {
         if (key !in this) keyNotFoundError(key)
         return source.map[key] as? Double ?: DEFAULT_DOUBLE
@@ -101,31 +114,42 @@
         return source.map[key] as? String ?: defaultValue()
     }
 
-    @Suppress("UNCHECKED_CAST")
+    actual inline fun getCharSequenceList(key: String): List<CharSequence> {
+        if (key !in this) keyNotFoundError(key)
+        @Suppress("UNCHECKED_CAST")
+        return source.map[key] as? List<CharSequence> ?: valueNotFoundError(key)
+    }
+
+    actual inline fun getCharSequenceListOrElse(
+        key: String,
+        defaultValue: () -> List<CharSequence>
+    ): List<CharSequence> {
+        if (key !in this) defaultValue()
+        @Suppress("UNCHECKED_CAST") return source.map[key] as? List<CharSequence> ?: defaultValue()
+    }
+
     actual inline fun getIntList(key: String): List<Int> {
         if (key !in this) keyNotFoundError(key)
-        return source.map[key] as? List<Int> ?: valueNotFoundError(key)
+        @Suppress("UNCHECKED_CAST") return source.map[key] as? List<Int> ?: valueNotFoundError(key)
     }
 
-    @Suppress("UNCHECKED_CAST")
     actual inline fun getIntListOrElse(key: String, defaultValue: () -> List<Int>): List<Int> {
         if (key !in this) defaultValue()
-        return source.map[key] as? List<Int> ?: defaultValue()
+        @Suppress("UNCHECKED_CAST") return source.map[key] as? List<Int> ?: defaultValue()
     }
 
-    @Suppress("UNCHECKED_CAST")
     actual inline fun getStringList(key: String): List<String> {
         if (key !in this) keyNotFoundError(key)
+        @Suppress("UNCHECKED_CAST")
         return source.map[key] as? List<String> ?: valueNotFoundError(key)
     }
 
-    @Suppress("UNCHECKED_CAST")
     actual inline fun getStringListOrElse(
         key: String,
         defaultValue: () -> List<String>
     ): List<String> {
         if (key !in this) defaultValue()
-        return source.map[key] as? List<String> ?: defaultValue()
+        @Suppress("UNCHECKED_CAST") return source.map[key] as? List<String> ?: defaultValue()
     }
 
     actual inline fun getCharArray(key: String): CharArray {
@@ -138,6 +162,20 @@
         return source.map[key] as? CharArray ?: defaultValue()
     }
 
+    actual inline fun getCharSequenceArray(key: String): Array<CharSequence> {
+        if (key !in this) keyNotFoundError(key)
+        @Suppress("UNCHECKED_CAST")
+        return source.map[key] as? Array<CharSequence> ?: valueNotFoundError(key)
+    }
+
+    actual inline fun getCharSequenceArrayOrElse(
+        key: String,
+        defaultValue: () -> Array<CharSequence>
+    ): Array<CharSequence> {
+        if (key !in this) defaultValue()
+        @Suppress("UNCHECKED_CAST") return source.map[key] as? Array<CharSequence> ?: defaultValue()
+    }
+
     actual inline fun getBooleanArray(key: String): BooleanArray {
         if (key !in this) keyNotFoundError(key)
         return source.map[key] as? BooleanArray ?: valueNotFoundError(key)
diff --git a/savedstate/savedstate/src/nonAndroidMain/kotlin/androidx/savedstate/SavedStateWriter.nonAndroid.kt b/savedstate/savedstate/src/nonAndroidMain/kotlin/androidx/savedstate/SavedStateWriter.nonAndroid.kt
index 95cecc4..88fac06 100644
--- a/savedstate/savedstate/src/nonAndroidMain/kotlin/androidx/savedstate/SavedStateWriter.nonAndroid.kt
+++ b/savedstate/savedstate/src/nonAndroidMain/kotlin/androidx/savedstate/SavedStateWriter.nonAndroid.kt
@@ -39,6 +39,10 @@
         source.map[key] = value
     }
 
+    actual inline fun putCharSequence(key: String, value: CharSequence) {
+        source.map[key] = value
+    }
+
     actual inline fun putDouble(key: String, value: Double) {
         source.map[key] = value
     }
@@ -63,6 +67,10 @@
         source.map[key] = value
     }
 
+    actual inline fun putCharSequenceList(key: String, values: List<CharSequence>) {
+        source.map[key] = values
+    }
+
     actual inline fun putIntList(key: String, values: List<Int>) {
         source.map[key] = values
     }
@@ -79,6 +87,10 @@
         source.map[key] = values
     }
 
+    actual inline fun putCharSequenceArray(key: String, values: Array<CharSequence>) {
+        source.map[key] = values
+    }
+
     actual inline fun putDoubleArray(key: String, values: DoubleArray) {
         source.map[key] = values
     }