Merge changes from topic "serialization-mutable-state" into androidx-main

* changes:
  Add `MutableStateSerializer` for serializing `MutableState`
  Move KMP compatible test dependencies to `commonTest`
diff --git a/lifecycle/lifecycle-viewmodel-compose/api/current.txt b/lifecycle/lifecycle-viewmodel-compose/api/current.txt
index ace8748..8372225 100644
--- a/lifecycle/lifecycle-viewmodel-compose/api/current.txt
+++ b/lifecycle/lifecycle-viewmodel-compose/api/current.txt
@@ -29,3 +29,12 @@
 
 }
 
+package androidx.lifecycle.viewmodel.compose.serialization.serializers {
+
+  public final class MutableStateSerializerKt {
+    method public static inline <reified T> kotlinx.serialization.KSerializer<androidx.compose.runtime.MutableState<T>> MutableStateSerializer();
+    method public static <T> kotlinx.serialization.KSerializer<androidx.compose.runtime.MutableState<T>> MutableStateSerializer(kotlinx.serialization.KSerializer<T> serializer);
+  }
+
+}
+
diff --git a/lifecycle/lifecycle-viewmodel-compose/api/restricted_current.txt b/lifecycle/lifecycle-viewmodel-compose/api/restricted_current.txt
index ace8748..8372225 100644
--- a/lifecycle/lifecycle-viewmodel-compose/api/restricted_current.txt
+++ b/lifecycle/lifecycle-viewmodel-compose/api/restricted_current.txt
@@ -29,3 +29,12 @@
 
 }
 
+package androidx.lifecycle.viewmodel.compose.serialization.serializers {
+
+  public final class MutableStateSerializerKt {
+    method public static inline <reified T> kotlinx.serialization.KSerializer<androidx.compose.runtime.MutableState<T>> MutableStateSerializer();
+    method public static <T> kotlinx.serialization.KSerializer<androidx.compose.runtime.MutableState<T>> MutableStateSerializer(kotlinx.serialization.KSerializer<T> serializer);
+  }
+
+}
+
diff --git a/lifecycle/lifecycle-viewmodel-compose/build.gradle b/lifecycle/lifecycle-viewmodel-compose/build.gradle
index c63ee18..6b1230c 100644
--- a/lifecycle/lifecycle-viewmodel-compose/build.gradle
+++ b/lifecycle/lifecycle-viewmodel-compose/build.gradle
@@ -30,6 +30,7 @@
     id("AndroidXPlugin")
     id("com.android.library")
     id("AndroidXComposePlugin")
+    alias(libs.plugins.kotlinSerialization)
 }
 
 androidXMultiplatform {
@@ -45,12 +46,17 @@
                 api(project(":lifecycle:lifecycle-viewmodel"))
                 api("androidx.annotation:annotation:1.8.1")
                 api("androidx.compose.runtime:runtime:1.6.0")
+                api(libs.kotlinSerializationCore)
                 implementation(libs.kotlinStdlib)
             }
         }
 
         commonTest {
-            // TODO(b/330323282): Move common dependencies here.
+            dependencies {
+                implementation(project(":lifecycle:lifecycle-viewmodel-savedstate"))
+                implementation(project(":lifecycle:lifecycle-viewmodel-testing"))
+                implementation(project(":lifecycle:lifecycle-runtime-testing"))
+            }
         }
 
         androidMain {
@@ -83,9 +89,7 @@
                 // but it doesn't work in androidx.
                 // See aosp/1804059
                 implementation(project(":lifecycle:lifecycle-common-java8"))
-                implementation(project(":lifecycle:lifecycle-viewmodel-savedstate"))
                 implementation(project(":activity:activity-compose"))
-                implementation(project(":lifecycle:lifecycle-runtime-testing"))
             }
         }
     }
diff --git a/lifecycle/lifecycle-viewmodel-compose/src/androidInstrumentedTest/kotlin/androidx/lifecycle/viewmodel/compose/serialization/serializers/MutableStateSerializerTest.android.kt b/lifecycle/lifecycle-viewmodel-compose/src/androidInstrumentedTest/kotlin/androidx/lifecycle/viewmodel/compose/serialization/serializers/MutableStateSerializerTest.android.kt
new file mode 100644
index 0000000..0cbeb73
--- /dev/null
+++ b/lifecycle/lifecycle-viewmodel-compose/src/androidInstrumentedTest/kotlin/androidx/lifecycle/viewmodel/compose/serialization/serializers/MutableStateSerializerTest.android.kt
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2025 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.lifecycle.viewmodel.compose.serialization.serializers
+
+import androidx.compose.runtime.mutableStateOf
+import androidx.savedstate.serialization.decodeFromSavedState
+import androidx.savedstate.serialization.encodeToSavedState
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.google.common.truth.Truth.assertThat
+import kotlinx.serialization.InternalSerializationApi
+import kotlinx.serialization.Serializable
+import kotlinx.serialization.serializer
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class MutableStateSerializerTest {
+
+    @Test
+    fun encodeDecode_withImplicitSerializer() {
+        val state = mutableStateOf(USER_JOHN_DOE)
+        val serializer = MutableStateSerializer<User>()
+
+        val encoded = encodeToSavedState(serializer, state)
+        val decoded = decodeFromSavedState(serializer, encoded)
+
+        assertThat(state.value).isEqualTo(decoded.value)
+    }
+
+    @Test
+    fun encodeDecode_withExplicitSerializer() {
+        val state = mutableStateOf(USER_JOHN_DOE)
+        val serializer = MutableStateSerializer(USER_SERIALIZER)
+
+        val encoded = encodeToSavedState(serializer, state)
+        val decoded = decodeFromSavedState(serializer, encoded)
+
+        assertThat(state.value).isEqualTo(decoded.value)
+    }
+
+    companion object {
+        val USER_JOHN_DOE = User(name = "John", surname = "Doe")
+        @OptIn(InternalSerializationApi::class) val USER_SERIALIZER = User::class.serializer()
+    }
+
+    @Serializable data class User(val name: String = "John", val surname: String = "Doe")
+}
diff --git a/lifecycle/lifecycle-viewmodel-compose/src/commonMain/kotlin/androidx/lifecycle/viewmodel/compose/serialization/serializers/MutableStateSerializer.kt b/lifecycle/lifecycle-viewmodel-compose/src/commonMain/kotlin/androidx/lifecycle/viewmodel/compose/serialization/serializers/MutableStateSerializer.kt
new file mode 100644
index 0000000..1bd43bd
--- /dev/null
+++ b/lifecycle/lifecycle-viewmodel-compose/src/commonMain/kotlin/androidx/lifecycle/viewmodel/compose/serialization/serializers/MutableStateSerializer.kt
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2025 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.
+ */
+
+@file:OptIn(InternalSerializationApi::class, ExperimentalTypeInference::class)
+
+package androidx.lifecycle.viewmodel.compose.serialization.serializers
+
+import androidx.compose.runtime.MutableState
+import androidx.compose.runtime.mutableStateOf
+import kotlin.experimental.ExperimentalTypeInference
+import kotlinx.serialization.InternalSerializationApi
+import kotlinx.serialization.KSerializer
+import kotlinx.serialization.descriptors.SerialDescriptor
+import kotlinx.serialization.encoding.Decoder
+import kotlinx.serialization.encoding.Encoder
+import kotlinx.serialization.serializer
+
+/**
+ * Creates a [KSerializer] for a [MutableState] containing a [Serializable] value of type [T].
+ *
+ * This inline function infers the state type [T] automatically and retrieves the appropriate
+ * [KSerializer] for serialization and deserialization of [MutableState].
+ *
+ * @param T The type of the value stored in the [MutableState].
+ * @return A [KSerializer] for handling [MutableState] containing a [Serializable] type [T].
+ */
+@Suppress("FunctionName")
+public inline fun <reified T> MutableStateSerializer(): KSerializer<MutableState<T>> {
+    return MutableStateSerializer(serializer())
+}
+
+/**
+ * Creates a [KSerializer] for a [MutableState] containing a [Serializable] value of type [T].
+ *
+ * This function allows for explicit specification of the [KSerializer] for the state type [T]. It
+ * provides serialization and deserialization capabilities for [MutableState] objects.
+ *
+ * @param T The type of the value stored in the [MutableState].
+ * @param serializer The [KSerializer] for the [Serializable] type [T].
+ * @return A [KSerializer] for handling [MutableState] containing a [Serializable] type [T].
+ */
+@Suppress("FunctionName")
+public fun <T> MutableStateSerializer(serializer: KSerializer<T>): KSerializer<MutableState<T>> {
+    return MutableStateSerializerImpl<T>(serializer)
+}
+
+/**
+ * Internal implementation of [KSerializer] for [MutableState].
+ *
+ * This private class wraps a [KSerializer] for the inner value type [T], enabling serialization and
+ * deserialization of [MutableState] instances. The inner value serialization is delegated to the
+ * provided [valueSerializer].
+ *
+ * @param T The type of the value stored in the [MutableState].
+ * @property valueSerializer The [KSerializer] used to serialize and deserialize the inner value.
+ */
+private class MutableStateSerializerImpl<T>(
+    private val valueSerializer: KSerializer<T>,
+) : KSerializer<MutableState<T>> {
+
+    override val descriptor: SerialDescriptor = valueSerializer.descriptor
+
+    override fun serialize(encoder: Encoder, value: MutableState<T>) {
+        valueSerializer.serialize(encoder, value.value)
+    }
+
+    override fun deserialize(decoder: Decoder): MutableState<T> {
+        return mutableStateOf(valueSerializer.deserialize(decoder))
+    }
+}