[go: nahoru, domu]

Deprecate savedInstanceState()

We will now automatically save and restore the MutableState objects created via mutableStateOf() factory function with the known SnapshotMutationPolicy provided. For custom SnapshotMutationPolicy objects users will have to create a custom Saver objects.

Relnote: Similarly to how we previously removed `state { 0 }` composable and now promote usage like `remember { mutableStateOf(0) }` we are going to remove `savedInstanceState { 0 }` composable. You should use `rememberSaveable { mutableStateOf(0) }` instead and it will save and restore automatically if the type used inside the MutableState can be stored in the Bundle. If previously you were passing a custom saver object now you need to use a new overload of rememberSaveable which has `stateSaver` parameter. The usage will look like this: `val holder = rememberSaveable(stateSaver = HolderSaver) { mutableStateOf(Holder(0)) }`
Fixes: 177338004
Test: manually, existing tests, new test in ActivityRecreationTest
Change-Id: Ib4c266902d166f119ea1770cccbc78ac25a54ff7
diff --git a/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/CrossfadeDemo.kt b/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/CrossfadeDemo.kt
index 5133519..16f7699 100644
--- a/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/CrossfadeDemo.kt
+++ b/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/CrossfadeDemo.kt
@@ -27,9 +27,9 @@
 import androidx.compose.foundation.layout.preferredHeight
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.saveable.rememberSaveable
 import androidx.compose.runtime.saveable.rememberSaveableStateHolder
-import androidx.compose.runtime.savedinstancestate.savedInstanceState
 import androidx.compose.runtime.setValue
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Color
@@ -39,7 +39,7 @@
 
 @Composable
 fun CrossfadeDemo() {
-    var current by savedInstanceState { 0 }
+    var current by rememberSaveable { mutableStateOf(0) }
     Column {
         Row {
             tabs.forEachIndexed { index, tab ->
diff --git a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/ListDemos.kt b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/ListDemos.kt
index f033246..7a5aeae 100644
--- a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/ListDemos.kt
+++ b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/ListDemos.kt
@@ -58,7 +58,7 @@
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
 import androidx.compose.runtime.rememberCoroutineScope
-import androidx.compose.runtime.savedinstancestate.savedInstanceState
+import androidx.compose.runtime.saveable.rememberSaveable
 import androidx.compose.runtime.setValue
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
@@ -472,7 +472,7 @@
             Modifier.padding(16.dp).size(200.dp).background(Color.LightGray),
             contentAlignment = Alignment.Center
         ) {
-            var state by savedInstanceState { 0 }
+            var state by rememberSaveable { mutableStateOf(0) }
             Button( state++ }) {
                 Text("Index=$index State=$state")
             }
diff --git a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/CapitalizationAutoCorrectDemo.kt b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/CapitalizationAutoCorrectDemo.kt
index d4cb846..ae9ddb2 100644
--- a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/CapitalizationAutoCorrectDemo.kt
+++ b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/CapitalizationAutoCorrectDemo.kt
@@ -24,7 +24,7 @@
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
-import androidx.compose.runtime.savedinstancestate.savedInstanceState
+import androidx.compose.runtime.saveable.rememberSaveable
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.text.ExperimentalTextApi
 import androidx.compose.ui.text.InternalTextApi
@@ -93,7 +93,9 @@
 )
 private fun MyTextField(data: ImeOptionsData) {
     val controller = remember { mutableStateOf<SoftwareKeyboardController?>(null) }
-    val state = savedInstanceState(saver = TextFieldValue.Saver) { TextFieldValue() }
+    val state = rememberSaveable(stateSaver = TextFieldValue.Saver) {
+        mutableStateOf(TextFieldValue())
+    }
     BasicTextField(
         modifier = demoTextFieldModifiers.defaultMinSizeConstraints(100.dp),
         value = state.value,
diff --git a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/ComposeInputField.kt b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/ComposeInputField.kt
index d83f336..ca65435 100644
--- a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/ComposeInputField.kt
+++ b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/ComposeInputField.kt
@@ -28,7 +28,7 @@
 import androidx.compose.runtime.Providers
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
-import androidx.compose.runtime.savedinstancestate.savedInstanceState
+import androidx.compose.runtime.saveable.rememberSaveable
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.platform.AmbientLayoutDirection
@@ -81,7 +81,7 @@
     text: String = ""
 ) {
     val controller = remember { mutableStateOf<SoftwareKeyboardController?>(null) }
-    val state = savedInstanceState { text }
+    val state = rememberSaveable { mutableStateOf(text) }
     BasicTextField(
         modifier = demoTextFieldModifiers,
         value = state.value,
diff --git a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/ComposeInputFieldFocusTransition.kt b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/ComposeInputFieldFocusTransition.kt
index 698b35d..b9b210f 100644
--- a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/ComposeInputFieldFocusTransition.kt
+++ b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/ComposeInputFieldFocusTransition.kt
@@ -24,7 +24,7 @@
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
-import androidx.compose.runtime.savedinstancestate.savedInstanceState
+import androidx.compose.runtime.saveable.rememberSaveable
 import androidx.compose.runtime.setValue
 import androidx.compose.ui.focus.FocusRequester
 import androidx.compose.ui.focus.focusRequester
@@ -53,7 +53,7 @@
     focusRequester: FocusRequester,
     nextFocusRequester: FocusRequester
 ) {
-    val state = savedInstanceState { "Focus Transition Test" }
+    val state = rememberSaveable { mutableStateOf("Focus Transition Test") }
     var color by remember { mutableStateOf(Black) }
 
     BasicTextField(
diff --git a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/ComposeInputFieldMinMaxLines.kt b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/ComposeInputFieldMinMaxLines.kt
index eb755df..3fb1007 100644
--- a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/ComposeInputFieldMinMaxLines.kt
+++ b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/ComposeInputFieldMinMaxLines.kt
@@ -19,7 +19,8 @@
 import androidx.compose.foundation.lazy.LazyColumn
 import androidx.compose.foundation.text.BasicTextField
 import androidx.compose.runtime.Composable
-import androidx.compose.runtime.savedinstancestate.savedInstanceState
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.saveable.rememberSaveable
 import androidx.compose.ui.draw.clipToBounds
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.text.InternalTextApi
@@ -54,7 +55,7 @@
 @Composable
 @OptIn(InternalTextApi::class)
 private fun TextFieldWithMaxLines(str: String? = null, maxLines: Int) {
-    val state = savedInstanceState { str ?: "abc ".repeat(20) }
+    val state = rememberSaveable { mutableStateOf(str ?: "abc ".repeat(20)) }
     BasicTextField(
         modifier = demoTextFieldModifiers.clipToBounds(),
         value = state.value,
diff --git a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/ComposeInputFieldTrickyUseCase.kt b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/ComposeInputFieldTrickyUseCase.kt
index d95e21e..ebc4ebe 100644
--- a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/ComposeInputFieldTrickyUseCase.kt
+++ b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/ComposeInputFieldTrickyUseCase.kt
@@ -20,7 +20,8 @@
 import androidx.compose.foundation.text.BasicTextField
 import androidx.compose.foundation.text.KeyboardOptions
 import androidx.compose.runtime.Composable
-import androidx.compose.runtime.savedinstancestate.savedInstanceState
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.saveable.rememberSaveable
 import androidx.compose.ui.text.TextStyle
 import androidx.compose.ui.text.input.KeyboardType
 import androidx.compose.ui.unit.sp
@@ -42,7 +43,7 @@
 
 @Composable
 private fun RejectNonDigits() {
-    val state = savedInstanceState { "" }
+    val state = rememberSaveable { mutableStateOf("") }
     BasicTextField(
         modifier = demoTextFieldModifiers,
         value = state.value,
@@ -58,7 +59,7 @@
 
 @Composable
 private fun RejectComposition() {
-    val state = savedInstanceState { "" }
+    val state = rememberSaveable { mutableStateOf(({ "" })()) }
     BasicTextField(
         modifier = demoTextFieldModifiers,
         value = state.value,
diff --git a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/ComposeVariousInputField.kt b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/ComposeVariousInputField.kt
index abc507b..48bf8cd 100644
--- a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/ComposeVariousInputField.kt
+++ b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/ComposeVariousInputField.kt
@@ -22,12 +22,13 @@
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.fillMaxWidth
 import androidx.compose.foundation.lazy.LazyColumn
-import androidx.compose.material.Text
 import androidx.compose.foundation.text.BasicTextField
 import androidx.compose.foundation.text.KeyboardOptions
+import androidx.compose.material.Text
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
-import androidx.compose.runtime.savedinstancestate.savedInstanceState
+import androidx.compose.runtime.saveable.rememberSaveable
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.text.AnnotatedString
@@ -252,7 +253,7 @@
     onValueChange: (String, String) -> String = { _, new -> new },
     visualTransformation: VisualTransformation
 ) {
-    val state = savedInstanceState { "" }
+    val state = rememberSaveable { mutableStateOf("") }
     BasicTextField(
         modifier = demoTextFieldModifiers,
         value = state.value,
@@ -272,7 +273,7 @@
 
 @Composable
 private fun HintEditText(content: @Composable () -> Unit) {
-    val state = savedInstanceState { "" }
+    val state = rememberSaveable { mutableStateOf("") }
 
     Box(demoTextFieldModifiers) {
         BasicTextField(
@@ -289,7 +290,9 @@
 
 @Composable
 private fun InteractionStateTextField() {
-    val state = savedInstanceState(saver = TextFieldValue.Saver) { TextFieldValue() }
+    val state = rememberSaveable(stateSaver = TextFieldValue.Saver) {
+        mutableStateOf(TextFieldValue())
+    }
     val interactionState = remember { InteractionState() }
 
     Column(demoTextFieldModifiers) {
diff --git a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/KeyboardSingleLineDemo.kt b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/KeyboardSingleLineDemo.kt
index 4783888..1bc5c66 100644
--- a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/KeyboardSingleLineDemo.kt
+++ b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/KeyboardSingleLineDemo.kt
@@ -24,7 +24,7 @@
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
-import androidx.compose.runtime.savedinstancestate.savedInstanceState
+import androidx.compose.runtime.saveable.rememberSaveable
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.text.ExperimentalTextApi
 import androidx.compose.ui.text.InternalTextApi
@@ -124,7 +124,9 @@
 )
 private fun MyTextField(data: ImeOptionsData) {
     val controller = remember { mutableStateOf<SoftwareKeyboardController?>(null) }
-    val state = savedInstanceState(saver = TextFieldValue.Saver) { TextFieldValue() }
+    val state = rememberSaveable(stateSaver = TextFieldValue.Saver) {
+        mutableStateOf(TextFieldValue())
+    }
     BasicTextField(
         modifier = demoTextFieldModifiers.defaultMinSizeConstraints(100.dp),
         value = state.value,
diff --git a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/TailFollowingTextField.kt b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/TailFollowingTextField.kt
index 88a72be..f013764 100644
--- a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/TailFollowingTextField.kt
+++ b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/TailFollowingTextField.kt
@@ -21,7 +21,8 @@
 import androidx.compose.foundation.layout.height
 import androidx.compose.foundation.text.BasicTextField
 import androidx.compose.runtime.Composable
-import androidx.compose.runtime.savedinstancestate.savedInstanceState
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.saveable.rememberSaveable
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.draw.clipToBounds
 import androidx.compose.ui.layout.Layout
@@ -34,7 +35,9 @@
 @Composable
 fun TailFollowingTextFieldDemo() {
     Column {
-        val hstate = savedInstanceState { "abc def ghi jkl mno pqr stu vwx yz" }
+        val hstate = rememberSaveable {
+            mutableStateOf("abc def ghi jkl mno pqr stu vwx yz")
+        }
         HorizontalTailFollowingTextField(
             value = hstate.value,
              hstate.value = it },
@@ -44,7 +47,9 @@
                 .clipToBounds()
         )
 
-        val vstate = savedInstanceState { "a\nb\nc\nd\ne\nf\ng\nh" }
+        val vstate = rememberSaveable {
+            mutableStateOf("a\nb\nc\nd\ne\nf\ng\nh")
+        }
         VerticalTailFollowintTextField(
             value = vstate.value,
              vstate.value = it },
diff --git a/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/BasicTextFieldSamples.kt b/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/BasicTextFieldSamples.kt
index d1cc274..de4e98c3 100644
--- a/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/BasicTextFieldSamples.kt
+++ b/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/BasicTextFieldSamples.kt
@@ -25,14 +25,15 @@
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.width
 import androidx.compose.foundation.shape.RoundedCornerShape
-import androidx.compose.material.Text
 import androidx.compose.foundation.text.BasicTextField
 import androidx.compose.material.Icon
+import androidx.compose.material.Text
 import androidx.compose.material.icons.Icons
 import androidx.compose.material.icons.filled.MailOutline
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.getValue
-import androidx.compose.runtime.savedinstancestate.savedInstanceState
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.saveable.rememberSaveable
 import androidx.compose.runtime.setValue
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Color
@@ -42,7 +43,9 @@
 @Sampled
 @Composable
 fun BasicTextFieldSample() {
-    var value by savedInstanceState(saver = TextFieldValue.Saver) { TextFieldValue() }
+    var value by rememberSaveable(stateSaver = TextFieldValue.Saver) {
+        mutableStateOf(TextFieldValue())
+    }
     BasicTextField(
         value = value,
         >
@@ -56,7 +59,7 @@
 @Sampled
 @Composable
 fun BasicTextFieldWithStringSample() {
-    var value by savedInstanceState { "initial value" }
+    var value by rememberSaveable { mutableStateOf("initial value") }
     BasicTextField(
         value = value,
         >
@@ -71,7 +74,7 @@
 @Composable
 @OptIn(ExperimentalFoundationApi::class)
 fun PlaceholderBasicTextFieldSample() {
-    var value by savedInstanceState { "initial value" }
+    var value by rememberSaveable { mutableStateOf("initial value") }
     Box {
         BasicTextField(
             value = value,
@@ -87,7 +90,7 @@
 @Composable
 @OptIn(ExperimentalFoundationApi::class)
 fun TextFieldWithIconSample() {
-    var value by savedInstanceState { "initial value" }
+    var value by rememberSaveable { mutableStateOf("initial value") }
     BasicTextField(
         value = value,
          value = it },
diff --git a/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/TextFieldSample.kt b/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/TextFieldSample.kt
index bb60c2e..a5570d9 100644
--- a/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/TextFieldSample.kt
+++ b/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/TextFieldSample.kt
@@ -23,7 +23,8 @@
 import androidx.compose.material.Text
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.getValue
-import androidx.compose.runtime.savedinstancestate.savedInstanceState
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.saveable.rememberSaveable
 import androidx.compose.runtime.setValue
 import androidx.compose.ui.text.input.TextFieldValue
 
@@ -32,7 +33,9 @@
 @OptIn(ExperimentalFoundationApi::class)
 @Suppress("DEPRECATION")
 fun TextFieldSample() {
-    var value by savedInstanceState(saver = TextFieldValue.Saver) { TextFieldValue() }
+    var value by rememberSaveable(stateSaver = TextFieldValue.Saver) {
+        mutableStateOf(TextFieldValue())
+    }
     BaseTextField(
         value = value,
          value = it }
@@ -44,7 +47,9 @@
 @OptIn(ExperimentalFoundationApi::class)
 @Suppress("DEPRECATION")
 fun PlaceholderTextFieldSample() {
-    val state = savedInstanceState(saver = TextFieldValue.Saver) { TextFieldValue() }
+    val state = rememberSaveable(stateSaver = TextFieldValue.Saver) {
+        mutableStateOf(TextFieldValue())
+    }
     Box {
         BaseTextField(
             value = state.value,
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/textfield/TextFieldTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/textfield/TextFieldTest.kt
index ca6be5a..e2342ac 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/textfield/TextFieldTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/textfield/TextFieldTest.kt
@@ -41,7 +41,7 @@
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
-import androidx.compose.runtime.savedinstancestate.savedInstanceState
+import androidx.compose.runtime.saveable.rememberSaveable
 import androidx.compose.runtime.setValue
 import androidx.compose.testutils.assertShape
 import androidx.compose.ui.Modifier
@@ -376,7 +376,7 @@
 
         val restorationTester = StateRestorationTester(rule)
         restorationTester.setContent {
-            state = savedInstanceState(saver = Saver) { TextFieldValue() }
+            state = rememberSaveable(stateSaver = Saver) { mutableStateOf(TextFieldValue()) }
         }
 
         rule.runOnIdle {
diff --git a/compose/integration-tests/demos/src/main/java/androidx/compose/integration/demos/DemoApp.kt b/compose/integration-tests/demos/src/main/java/androidx/compose/integration/demos/DemoApp.kt
index f84c765..4136fb9 100644
--- a/compose/integration-tests/demos/src/main/java/androidx/compose/integration/demos/DemoApp.kt
+++ b/compose/integration-tests/demos/src/main/java/androidx/compose/integration/demos/DemoApp.kt
@@ -45,7 +45,8 @@
 import androidx.compose.material.icons.filled.Settings
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.getValue
-import androidx.compose.runtime.savedinstancestate.savedInstanceState
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.saveable.rememberSaveable
 import androidx.compose.runtime.setValue
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
@@ -68,7 +69,7 @@
 ) {
     val navigationIcon = (@Composable { AppBarIcons.Back(onNavigateUp) }).takeIf { canNavigateUp }
 
-    var filterText by savedInstanceState { "" }
+    var filterText by rememberSaveable { mutableStateOf("") }
 
     Scaffold(
         topBar = {
diff --git a/compose/integration-tests/docs-snippets/src/main/java/androidx/compose/integration/docs/interoperability/Interoperability.kt b/compose/integration-tests/docs-snippets/src/main/java/androidx/compose/integration/docs/interoperability/Interoperability.kt
index badd5b5..589bddd 100644
--- a/compose/integration-tests/docs-snippets/src/main/java/androidx/compose/integration/docs/interoperability/Interoperability.kt
+++ b/compose/integration-tests/docs-snippets/src/main/java/androidx/compose/integration/docs/interoperability/Interoperability.kt
@@ -66,7 +66,7 @@
 import androidx.compose.runtime.rememberUpdatedState
 import androidx.compose.runtime.saveable.listSaver
 import androidx.compose.runtime.saveable.mapSaver
-import androidx.compose.runtime.savedinstancestate.savedInstanceState
+import androidx.compose.runtime.saveable.rememberSaveable
 import androidx.compose.runtime.setValue
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
@@ -367,7 +367,7 @@
 private object InteropSnippet15 {
     @Composable
     fun MyExample() {
-        var selectedId by savedInstanceState<String?> { null }
+        var selectedId by rememberSaveable { mutableStateOf<String?>(null) }
         /*...*/
     }
 }
@@ -380,7 +380,7 @@
 
     @Composable
     fun MyExample() {
-        var selectedCity = savedInstanceState { City("Madrid", "Spain") }
+        var selectedCity = rememberSaveable { mutableStateOf(City("Madrid", "Spain")) }
     }
      */
 }
@@ -399,7 +399,9 @@
 
     @Composable
     fun MyExample() {
-        var selectedCity = savedInstanceState(CitySaver) { City("Madrid", "Spain") }
+        var selectedCity = rememberSaveable(stateSaver = CitySaver) {
+            mutableStateOf(City("Madrid", "Spain"))
+        }
     }
 }
 
@@ -413,7 +415,9 @@
 
     @Composable
     fun MyExample() {
-        var selectedCity = savedInstanceState(CitySaver) { City("Madrid", "Spain") }
+        var selectedCity = rememberSaveable(stateSaver = CitySaver) {
+            mutableStateOf(City("Madrid", "Spain"))
+        }
         /*...*/
     }
 }
diff --git a/compose/integration-tests/docs-snippets/src/main/java/androidx/compose/integration/docs/state/State.kt b/compose/integration-tests/docs-snippets/src/main/java/androidx/compose/integration/docs/state/State.kt
index 3d70e48..f4cafe1 100644
--- a/compose/integration-tests/docs-snippets/src/main/java/androidx/compose/integration/docs/state/State.kt
+++ b/compose/integration-tests/docs-snippets/src/main/java/androidx/compose/integration/docs/state/State.kt
@@ -44,7 +44,7 @@
 import androidx.compose.runtime.livedata.observeAsState
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
-import androidx.compose.runtime.savedinstancestate.savedInstanceState
+import androidx.compose.runtime.saveable.rememberSaveable
 import androidx.compose.runtime.setValue
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.res.stringResource
@@ -313,7 +313,7 @@
 private object StateSnippet13 {
     @Composable
     fun ExpandingCard(title: String, body: String) {
-        var expanded by savedInstanceState { false }
+        var expanded by rememberSaveable { mutableStateOf(false) }
         ExpandingCard(
             title = title,
             body = body,
diff --git a/compose/material/material/integration-tests/material-demos/src/main/java/androidx/compose/material/demos/MaterialTextField.kt b/compose/material/material/integration-tests/material-demos/src/main/java/androidx/compose/material/demos/MaterialTextField.kt
index dc48864..275d7b4 100644
--- a/compose/material/material/integration-tests/material-demos/src/main/java/androidx/compose/material/demos/MaterialTextField.kt
+++ b/compose/material/material/integration-tests/material-demos/src/main/java/androidx/compose/material/demos/MaterialTextField.kt
@@ -57,7 +57,7 @@
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
-import androidx.compose.runtime.savedinstancestate.savedInstanceState
+import androidx.compose.runtime.saveable.rememberSaveable
 import androidx.compose.runtime.setValue
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
@@ -150,15 +150,15 @@
 @Composable
 fun MaterialTextFieldDemo() {
     Column(Modifier.verticalScroll(rememberScrollState()).padding(PaddingValues(10.dp))) {
-        var text by savedInstanceState { "" }
-        var leadingChecked by savedInstanceState { false }
-        var trailingChecked by savedInstanceState { false }
-        val characterCounterChecked by savedInstanceState { false }
-        var singleLineChecked by savedInstanceState { true }
-        var selectedOption by savedInstanceState { Option.None }
-        var selectedTextField by savedInstanceState { TextFieldType.Filled }
-        var disabled by savedInstanceState { false }
-        var readOnly by savedInstanceState { false }
+        var text by rememberSaveable { mutableStateOf("") }
+        var leadingChecked by rememberSaveable { mutableStateOf(false) }
+        var trailingChecked by rememberSaveable { mutableStateOf(false) }
+        val characterCounterChecked by rememberSaveable { mutableStateOf(false) }
+        var singleLineChecked by rememberSaveable { mutableStateOf(true) }
+        var selectedOption by rememberSaveable { mutableStateOf(Option.None) }
+        var selectedTextField by rememberSaveable { mutableStateOf(TextFieldType.Filled) }
+        var disabled by rememberSaveable { mutableStateOf(false) }
+        var readOnly by rememberSaveable { mutableStateOf(false) }
 
         val textField: @Composable () -> Unit = @Composable {
             when (selectedTextField) {
diff --git a/compose/material/material/samples/src/main/java/androidx/compose/material/samples/TextFieldSamples.kt b/compose/material/material/samples/src/main/java/androidx/compose/material/samples/TextFieldSamples.kt
index f631a97..07e7080 100644
--- a/compose/material/material/samples/src/main/java/androidx/compose/material/samples/TextFieldSamples.kt
+++ b/compose/material/material/samples/src/main/java/androidx/compose/material/samples/TextFieldSamples.kt
@@ -31,7 +31,8 @@
 import androidx.compose.material.icons.filled.Info
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.getValue
-import androidx.compose.runtime.savedinstancestate.savedInstanceState
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.saveable.rememberSaveable
 import androidx.compose.runtime.setValue
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.text.TextRange
@@ -44,7 +45,7 @@
 @Sampled
 @Composable
 fun SimpleTextFieldSample() {
-    var text by savedInstanceState { "" }
+    var text by rememberSaveable { mutableStateOf("") }
 
     TextField(
         value = text,
@@ -57,7 +58,7 @@
 @Sampled
 @Composable
 fun SimpleOutlinedTextFieldSample() {
-    var text by savedInstanceState { "" }
+    var text by rememberSaveable { mutableStateOf("") }
 
     OutlinedTextField(
         value = text,
@@ -69,7 +70,7 @@
 @Sampled
 @Composable
 fun TextFieldWithIcons() {
-    var text by savedInstanceState { "" }
+    var text by rememberSaveable { mutableStateOf("") }
 
     TextField(
         value = text,
@@ -83,7 +84,7 @@
 @Sampled
 @Composable
 fun TextFieldWithPlaceholder() {
-    var text by savedInstanceState { "" }
+    var text by rememberSaveable { mutableStateOf("") }
 
     TextField(
         value = text,
@@ -96,7 +97,7 @@
 @Sampled
 @Composable
 fun TextFieldWithErrorState() {
-    var text by savedInstanceState { "" }
+    var text by rememberSaveable { mutableStateOf("") }
     val isValid = text.count() > 5 && '@' in text
 
     TextField(
@@ -113,7 +114,7 @@
 @Sampled
 @Composable
 fun TextFieldWithHelperMessage() {
-    var text by savedInstanceState { "" }
+    var text by rememberSaveable { mutableStateOf("") }
     val invalidInput = text.count() < 5 || '@' !in text
 
     Column {
@@ -142,7 +143,7 @@
 @Sampled
 @Composable
 fun PasswordTextField() {
-    var password by savedInstanceState { "" }
+    var password by rememberSaveable { mutableStateOf("") }
     TextField(
         value = password,
          password = it },
@@ -155,8 +156,8 @@
 @Sampled
 @Composable
 fun TextFieldSample() {
-    var text by savedInstanceState(saver = TextFieldValue.Saver) {
-        TextFieldValue("example", TextRange(0, 7))
+    var text by rememberSaveable(stateSaver = TextFieldValue.Saver) {
+        mutableStateOf(TextFieldValue("example", TextRange(0, 7)))
     }
 
     TextField(
@@ -169,8 +170,8 @@
 @Sampled
 @Composable
 fun OutlinedTextFieldSample() {
-    var text by savedInstanceState(saver = TextFieldValue.Saver) {
-        TextFieldValue("example", TextRange(0, 7))
+    var text by rememberSaveable(stateSaver = TextFieldValue.Saver) {
+        mutableStateOf(TextFieldValue("example", TextRange(0, 7)))
     }
 
     OutlinedTextField(
@@ -183,7 +184,7 @@
 @Sampled
 @Composable
 fun TextFieldWithHideKeyboardOnImeAction() {
-    var text by savedInstanceState { "" }
+    var text by rememberSaveable { mutableStateOf("") }
 
     TextField(
         value = text,
diff --git a/compose/runtime/runtime-saveable/api/current.txt b/compose/runtime/runtime-saveable/api/current.txt
index 0aedbbf..f7e8664 100644
--- a/compose/runtime/runtime-saveable/api/current.txt
+++ b/compose/runtime/runtime-saveable/api/current.txt
@@ -11,6 +11,7 @@
 
   public final class RememberSaveableKt {
     method @androidx.compose.runtime.Composable public static <T> T rememberSaveable(Object![]? inputs, optional androidx.compose.runtime.saveable.Saver<T,?> saver, optional String? key, kotlin.jvm.functions.Function0<? extends T> init);
+    method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.MutableState<T> rememberSaveable(Object![]? inputs, androidx.compose.runtime.saveable.Saver<T,?> stateSaver, optional String? key, kotlin.jvm.functions.Function0<? extends androidx.compose.runtime.MutableState<T>> init);
   }
 
   public interface SaveableStateHolder {
@@ -65,6 +66,9 @@
     method @Deprecated public static <T> androidx.compose.runtime.savedinstancestate.Saver<T,?> mapSaver(kotlin.jvm.functions.Function2<? super androidx.compose.runtime.savedinstancestate.SaverScope,? super T,? extends java.util.Map<java.lang.String,?>> save, kotlin.jvm.functions.Function1<? super java.util.Map<java.lang.String,?>,? extends T> restore);
     method @Deprecated @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.savedinstancestate.RestorableStateHolder<T> rememberRestorableStateHolder();
     method @Deprecated @androidx.compose.runtime.Composable public static <T> T rememberSavedInstanceState(Object![]? inputs, optional androidx.compose.runtime.savedinstancestate.Saver<T,?>? saver, optional String? key, kotlin.jvm.functions.Function0<? extends T> init);
+    method @Deprecated @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.MutableState<T> savedInstanceState(optional String? key, kotlin.jvm.functions.Function0<? extends T> init);
+    method @Deprecated @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.MutableState<T> savedInstanceState(androidx.compose.runtime.savedinstancestate.Saver<T,?> saver, optional String? key, kotlin.jvm.functions.Function0<? extends T> init);
+    method @Deprecated @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.MutableState<T> savedInstanceState(androidx.compose.runtime.saveable.Saver<T,?> saver, optional String? key, kotlin.jvm.functions.Function0<? extends T> init);
   }
 
   @Deprecated public @interface ExperimentalRestorableStateHolder {
@@ -73,10 +77,6 @@
   @Deprecated public interface RestorableStateHolder<T> extends androidx.compose.runtime.saveable.SaveableStateHolder {
   }
 
-  public final class SavedInstanceStateKt {
-    method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.MutableState<T> savedInstanceState(Object![]? inputs, optional androidx.compose.runtime.saveable.Saver<T,?> saver, optional String? key, optional androidx.compose.runtime.SnapshotMutationPolicy<T> policy, kotlin.jvm.functions.Function0<? extends T> init);
-  }
-
   @Deprecated public interface Saver<Original, Saveable> extends androidx.compose.runtime.saveable.Saver<Original,Saveable> {
   }
 
diff --git a/compose/runtime/runtime-saveable/api/public_plus_experimental_current.txt b/compose/runtime/runtime-saveable/api/public_plus_experimental_current.txt
index 0aedbbf..f7e8664 100644
--- a/compose/runtime/runtime-saveable/api/public_plus_experimental_current.txt
+++ b/compose/runtime/runtime-saveable/api/public_plus_experimental_current.txt
@@ -11,6 +11,7 @@
 
   public final class RememberSaveableKt {
     method @androidx.compose.runtime.Composable public static <T> T rememberSaveable(Object![]? inputs, optional androidx.compose.runtime.saveable.Saver<T,?> saver, optional String? key, kotlin.jvm.functions.Function0<? extends T> init);
+    method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.MutableState<T> rememberSaveable(Object![]? inputs, androidx.compose.runtime.saveable.Saver<T,?> stateSaver, optional String? key, kotlin.jvm.functions.Function0<? extends androidx.compose.runtime.MutableState<T>> init);
   }
 
   public interface SaveableStateHolder {
@@ -65,6 +66,9 @@
     method @Deprecated public static <T> androidx.compose.runtime.savedinstancestate.Saver<T,?> mapSaver(kotlin.jvm.functions.Function2<? super androidx.compose.runtime.savedinstancestate.SaverScope,? super T,? extends java.util.Map<java.lang.String,?>> save, kotlin.jvm.functions.Function1<? super java.util.Map<java.lang.String,?>,? extends T> restore);
     method @Deprecated @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.savedinstancestate.RestorableStateHolder<T> rememberRestorableStateHolder();
     method @Deprecated @androidx.compose.runtime.Composable public static <T> T rememberSavedInstanceState(Object![]? inputs, optional androidx.compose.runtime.savedinstancestate.Saver<T,?>? saver, optional String? key, kotlin.jvm.functions.Function0<? extends T> init);
+    method @Deprecated @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.MutableState<T> savedInstanceState(optional String? key, kotlin.jvm.functions.Function0<? extends T> init);
+    method @Deprecated @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.MutableState<T> savedInstanceState(androidx.compose.runtime.savedinstancestate.Saver<T,?> saver, optional String? key, kotlin.jvm.functions.Function0<? extends T> init);
+    method @Deprecated @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.MutableState<T> savedInstanceState(androidx.compose.runtime.saveable.Saver<T,?> saver, optional String? key, kotlin.jvm.functions.Function0<? extends T> init);
   }
 
   @Deprecated public @interface ExperimentalRestorableStateHolder {
@@ -73,10 +77,6 @@
   @Deprecated public interface RestorableStateHolder<T> extends androidx.compose.runtime.saveable.SaveableStateHolder {
   }
 
-  public final class SavedInstanceStateKt {
-    method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.MutableState<T> savedInstanceState(Object![]? inputs, optional androidx.compose.runtime.saveable.Saver<T,?> saver, optional String? key, optional androidx.compose.runtime.SnapshotMutationPolicy<T> policy, kotlin.jvm.functions.Function0<? extends T> init);
-  }
-
   @Deprecated public interface Saver<Original, Saveable> extends androidx.compose.runtime.saveable.Saver<Original,Saveable> {
   }
 
diff --git a/compose/runtime/runtime-saveable/api/restricted_current.txt b/compose/runtime/runtime-saveable/api/restricted_current.txt
index 0aedbbf..f7e8664 100644
--- a/compose/runtime/runtime-saveable/api/restricted_current.txt
+++ b/compose/runtime/runtime-saveable/api/restricted_current.txt
@@ -11,6 +11,7 @@
 
   public final class RememberSaveableKt {
     method @androidx.compose.runtime.Composable public static <T> T rememberSaveable(Object![]? inputs, optional androidx.compose.runtime.saveable.Saver<T,?> saver, optional String? key, kotlin.jvm.functions.Function0<? extends T> init);
+    method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.MutableState<T> rememberSaveable(Object![]? inputs, androidx.compose.runtime.saveable.Saver<T,?> stateSaver, optional String? key, kotlin.jvm.functions.Function0<? extends androidx.compose.runtime.MutableState<T>> init);
   }
 
   public interface SaveableStateHolder {
@@ -65,6 +66,9 @@
     method @Deprecated public static <T> androidx.compose.runtime.savedinstancestate.Saver<T,?> mapSaver(kotlin.jvm.functions.Function2<? super androidx.compose.runtime.savedinstancestate.SaverScope,? super T,? extends java.util.Map<java.lang.String,?>> save, kotlin.jvm.functions.Function1<? super java.util.Map<java.lang.String,?>,? extends T> restore);
     method @Deprecated @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.savedinstancestate.RestorableStateHolder<T> rememberRestorableStateHolder();
     method @Deprecated @androidx.compose.runtime.Composable public static <T> T rememberSavedInstanceState(Object![]? inputs, optional androidx.compose.runtime.savedinstancestate.Saver<T,?>? saver, optional String? key, kotlin.jvm.functions.Function0<? extends T> init);
+    method @Deprecated @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.MutableState<T> savedInstanceState(optional String? key, kotlin.jvm.functions.Function0<? extends T> init);
+    method @Deprecated @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.MutableState<T> savedInstanceState(androidx.compose.runtime.savedinstancestate.Saver<T,?> saver, optional String? key, kotlin.jvm.functions.Function0<? extends T> init);
+    method @Deprecated @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.MutableState<T> savedInstanceState(androidx.compose.runtime.saveable.Saver<T,?> saver, optional String? key, kotlin.jvm.functions.Function0<? extends T> init);
   }
 
   @Deprecated public @interface ExperimentalRestorableStateHolder {
@@ -73,10 +77,6 @@
   @Deprecated public interface RestorableStateHolder<T> extends androidx.compose.runtime.saveable.SaveableStateHolder {
   }
 
-  public final class SavedInstanceStateKt {
-    method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.MutableState<T> savedInstanceState(Object![]? inputs, optional androidx.compose.runtime.saveable.Saver<T,?> saver, optional String? key, optional androidx.compose.runtime.SnapshotMutationPolicy<T> policy, kotlin.jvm.functions.Function0<? extends T> init);
-  }
-
   @Deprecated public interface Saver<Original, Saveable> extends androidx.compose.runtime.saveable.Saver<Original,Saveable> {
   }
 
diff --git a/compose/runtime/runtime-saveable/samples/src/main/java/androidx/compose/runtime/saveable/samples/RememberSaveableSamples.kt b/compose/runtime/runtime-saveable/samples/src/main/java/androidx/compose/runtime/saveable/samples/RememberSaveableSamples.kt
index 0c983de..5b4a546 100644
--- a/compose/runtime/runtime-saveable/samples/src/main/java/androidx/compose/runtime/saveable/samples/RememberSaveableSamples.kt
+++ b/compose/runtime/runtime-saveable/samples/src/main/java/androidx/compose/runtime/saveable/samples/RememberSaveableSamples.kt
@@ -20,10 +20,39 @@
 
 import androidx.annotation.Sampled
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.saveable.Saver
 import androidx.compose.runtime.saveable.rememberSaveable
+import androidx.compose.runtime.setValue
 
 @Sampled
 @Composable
 fun RememberSaveable() {
     val list = rememberSaveable { mutableListOf<Int>() }
 }
+
+@Sampled
+@Composable
+fun RememberSaveableWithMutableState() {
+    var value by rememberSaveable { mutableStateOf(({ "value" })()) }
+}
+
+@Sampled
+@Composable
+fun RememberSaveableCustomSaver() {
+    val holder = rememberSaveable(saver = HolderSaver) { Holder(0) }
+}
+
+@Sampled
+@Composable
+fun RememberSaveableWithMutableStateAndCustomSaver() {
+    val holder = rememberSaveable(stateSaver = HolderSaver) { mutableStateOf(Holder(0)) }
+}
+
+private data class Holder(var value: Int)
+
+private val HolderSaver = Saver<Holder, Int>(
+    save = { it.value },
+    restore = { Holder(it) }
+)
\ No newline at end of file
diff --git a/compose/runtime/runtime-saveable/samples/src/main/java/androidx/compose/runtime/saveable/samples/SaveableStateHolderSamples.kt b/compose/runtime/runtime-saveable/samples/src/main/java/androidx/compose/runtime/saveable/samples/SaveableStateHolderSamples.kt
index 40ca1e1..8c5feb7 100644
--- a/compose/runtime/runtime-saveable/samples/src/main/java/androidx/compose/runtime/saveable/samples/SaveableStateHolderSamples.kt
+++ b/compose/runtime/runtime-saveable/samples/src/main/java/androidx/compose/runtime/saveable/samples/SaveableStateHolderSamples.kt
@@ -29,8 +29,9 @@
 import androidx.compose.material.Text
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.saveable.rememberSaveable
 import androidx.compose.runtime.saveable.rememberSaveableStateHolder
-import androidx.compose.runtime.savedinstancestate.savedInstanceState
 import androidx.compose.runtime.setValue
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Color
@@ -58,7 +59,7 @@
     }
 
     Column {
-        var screen by savedInstanceState { "screen1" }
+        var screen by rememberSaveable { mutableStateOf("screen1") }
         Row(horizontalArrangement = Arrangement.SpaceEvenly) {
             Button( screen = "screen1" }) {
                 Text("Go to screen1")
@@ -79,7 +80,7 @@
 
 @Composable
 fun Screen1() {
-    var counter by savedInstanceState { 0 }
+    var counter by rememberSaveable { mutableStateOf(0) }
     Button( counter++ }) {
         Text("Counter=$counter on Screen1")
     }
diff --git a/compose/runtime/runtime-saveable/samples/src/main/java/androidx/compose/runtime/savedinstancestate/samples/Samples.kt b/compose/runtime/runtime-saveable/samples/src/main/java/androidx/compose/runtime/savedinstancestate/samples/Samples.kt
deleted file mode 100644
index 060e9bd..0000000
--- a/compose/runtime/runtime-saveable/samples/src/main/java/androidx/compose/runtime/savedinstancestate/samples/Samples.kt
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright 2020 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:Suppress("UNUSED_VARIABLE")
-
-package androidx.compose.runtime.savedinstancestate.samples
-
-import androidx.annotation.Sampled
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.getValue
-import androidx.compose.runtime.savedinstancestate.savedInstanceState
-import androidx.compose.runtime.setValue
-
-@Sampled
-@Composable
-fun SavedInstanceStateSample() {
-    var value by savedInstanceState { "value" }
-}
diff --git a/compose/runtime/runtime-saveable/src/androidAndroidTest/AndroidManifest.xml b/compose/runtime/runtime-saveable/src/androidAndroidTest/AndroidManifest.xml
index 7aeb38a..e5e4475 100644
--- a/compose/runtime/runtime-saveable/src/androidAndroidTest/AndroidManifest.xml
+++ b/compose/runtime/runtime-saveable/src/androidAndroidTest/AndroidManifest.xml
@@ -22,9 +22,10 @@
         android:debuggable="false"
         tools:ignore="HardcodedDebugMode"
         tools:replace="android:debuggable">
-        <activity android:name="androidx.compose.runtime.savedinstancestate.RecreationTest1Activity" />
-        <activity android:name="androidx.compose.runtime.savedinstancestate.RecreationTest2Activity" />
-        <activity android:name="androidx.compose.runtime.savedinstancestate.RecreationTest3Activity" />
-        <activity android:name="androidx.compose.runtime.savedinstancestate.RecreationTest4Activity" />
+        <activity android:name="androidx.compose.runtime.saveable.RecreationTest1Activity" />
+        <activity android:name="androidx.compose.runtime.saveable.RecreationTest2Activity" />
+        <activity android:name="androidx.compose.runtime.saveable.RecreationTest3Activity" />
+        <activity android:name="androidx.compose.runtime.saveable.RecreationTest4Activity" />
+        <activity android:name="androidx.compose.runtime.saveable.RecreationTest5Activity" />
     </application>
 </manifest>
diff --git a/compose/runtime/runtime-saveable/src/androidAndroidTest/kotlin/androidx/compose/runtime/saveable/ActivityRecreationTest.kt b/compose/runtime/runtime-saveable/src/androidAndroidTest/kotlin/androidx/compose/runtime/saveable/ActivityRecreationTest.kt
index bf075ff..c8e912e 100644
--- a/compose/runtime/runtime-saveable/src/androidAndroidTest/kotlin/androidx/compose/runtime/saveable/ActivityRecreationTest.kt
+++ b/compose/runtime/runtime-saveable/src/androidAndroidTest/kotlin/androidx/compose/runtime/saveable/ActivityRecreationTest.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package androidx.compose.runtime.savedinstancestate
+package androidx.compose.runtime.saveable
 
 import android.os.Bundle
 import android.view.LayoutInflater
@@ -22,8 +22,9 @@
 import android.widget.FrameLayout
 import android.widget.LinearLayout
 import androidx.activity.ComponentActivity
+import androidx.compose.runtime.MutableState
+import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
-import androidx.compose.runtime.saveable.rememberSaveable
 import androidx.compose.runtime.saveable.test.R
 import androidx.compose.ui.platform.ComposeView
 import androidx.compose.ui.platform.setContent
@@ -131,6 +132,26 @@
         }
     }
 
+    @Test
+    fun valueStoredInMutableStateIsRestored() {
+        val activityScenario: ActivityScenario<RecreationTest5Activity> =
+            ActivityScenario.launch(RecreationTest5Activity::class.java)
+
+        activityScenario.moveToState(Lifecycle.State.RESUMED)
+
+        activityScenario.onActivity {
+            assertThat(it.state.value).isEqualTo(0)
+            // change the value, so we can assert this change will be restored
+            it.state.value = 1
+        }
+
+        activityScenario.recreate()
+
+        activityScenario.onActivity {
+            assertThat(it.state.value).isEqualTo(1)
+        }
+    }
+
     private fun FragmentActivity.findFragment(id: Int) =
         supportFragmentManager.findFragmentById(id) as TestFragment
 }
@@ -225,6 +246,18 @@
     }
 }
 
+class RecreationTest5Activity : ComponentActivity() {
+
+    lateinit var state: MutableState<Int>
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        setContent {
+            state = rememberSaveable { mutableStateOf(0) }
+        }
+    }
+}
+
 class TestFragment : Fragment() {
 
     lateinit var array: IntArray
diff --git a/compose/runtime/runtime-saveable/src/androidAndroidTest/kotlin/androidx/compose/runtime/savedinstancestate/SavedInstanceStateTest.kt b/compose/runtime/runtime-saveable/src/androidAndroidTest/kotlin/androidx/compose/runtime/saveable/RememberSaveableWithMutableStateTest.kt
similarity index 86%
rename from compose/runtime/runtime-saveable/src/androidAndroidTest/kotlin/androidx/compose/runtime/savedinstancestate/SavedInstanceStateTest.kt
rename to compose/runtime/runtime-saveable/src/androidAndroidTest/kotlin/androidx/compose/runtime/saveable/RememberSaveableWithMutableStateTest.kt
index 75426ad..94d96e7 100644
--- a/compose/runtime/runtime-saveable/src/androidAndroidTest/kotlin/androidx/compose/runtime/savedinstancestate/SavedInstanceStateTest.kt
+++ b/compose/runtime/runtime-saveable/src/androidAndroidTest/kotlin/androidx/compose/runtime/saveable/RememberSaveableWithMutableStateTest.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright 2020 The Android Open Source Project
+ * Copyright 2021 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.
@@ -14,11 +14,10 @@
  * limitations under the License.
  */
 
-package androidx.compose.runtime.savedinstancestate
+package androidx.compose.runtime.saveable
 
 import androidx.compose.runtime.MutableState
-import androidx.compose.runtime.saveable.Holder
-import androidx.compose.runtime.saveable.HolderSaver
+import androidx.compose.runtime.mutableStateOf
 import androidx.compose.ui.test.junit4.StateRestorationTester
 import androidx.compose.ui.test.junit4.createComposeRule
 import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -30,7 +29,7 @@
 
 @MediumTest
 @RunWith(AndroidJUnit4::class)
-class SavedInstanceStateTest {
+class RememberSaveableWithMutableStateTest {
 
     @get:Rule
     val rule = createComposeRule()
@@ -41,7 +40,7 @@
     fun simpleRestore() {
         var state: MutableState<Int>? = null
         restorationTester.setContent {
-            state = savedInstanceState { 0 }
+            state = rememberSaveable { mutableStateOf(0) }
         }
 
         rule.runOnUiThread {
@@ -63,8 +62,8 @@
     fun restoreWithSaver() {
         var state: MutableState<Holder>? = null
         restorationTester.setContent {
-            state = savedInstanceState(saver = HolderSaver) {
-                Holder(0)
+            state = rememberSaveable(stateSaver = HolderSaver) {
+                mutableStateOf(Holder(0))
             }
         }
 
@@ -87,7 +86,7 @@
     fun nullableStateRestoresNonNullValue() {
         var state: MutableState<String?>? = null
         restorationTester.setContent {
-            state = savedInstanceState<String?> { null }
+            state = rememberSaveable { mutableStateOf(null) }
         }
 
         rule.runOnUiThread {
@@ -109,7 +108,7 @@
     fun nullableStateRestoresNullValue() {
         var state: MutableState<String?>? = null
         restorationTester.setContent {
-            state = savedInstanceState<String?> { "initial" }
+            state = rememberSaveable { mutableStateOf("initial") }
         }
 
         rule.runOnUiThread {
diff --git a/compose/runtime/runtime-saveable/src/androidAndroidTest/kotlin/androidx/compose/runtime/savedinstancestate/RestorationInVariousScenariosTest.kt b/compose/runtime/runtime-saveable/src/androidAndroidTest/kotlin/androidx/compose/runtime/saveable/RestorationInVariousScenariosTest.kt
similarity index 90%
rename from compose/runtime/runtime-saveable/src/androidAndroidTest/kotlin/androidx/compose/runtime/savedinstancestate/RestorationInVariousScenariosTest.kt
rename to compose/runtime/runtime-saveable/src/androidAndroidTest/kotlin/androidx/compose/runtime/saveable/RestorationInVariousScenariosTest.kt
index 9722ab5..20b47f6 100644
--- a/compose/runtime/runtime-saveable/src/androidAndroidTest/kotlin/androidx/compose/runtime/savedinstancestate/RestorationInVariousScenariosTest.kt
+++ b/compose/runtime/runtime-saveable/src/androidAndroidTest/kotlin/androidx/compose/runtime/saveable/RestorationInVariousScenariosTest.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright 2020 The Android Open Source Project
+ * Copyright 2021 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.
@@ -14,11 +14,12 @@
  * limitations under the License.
  */
 
-package androidx.compose.runtime.savedinstancestate
+package androidx.compose.runtime.saveable
 
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.MutableState
 import androidx.compose.runtime.key
+import androidx.compose.runtime.mutableStateOf
 import androidx.compose.ui.test.junit4.StateRestorationTester
 import androidx.compose.ui.test.junit4.createComposeRule
 import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -42,7 +43,7 @@
         val states = arrayOfNulls<MutableState<Int>>(2)
         restorationTester.setContent {
             for (i in 0..1) {
-                states[i] = savedInstanceState { 0 }
+                states[i] = rememberSaveable { mutableStateOf(0) }
             }
         }
 
@@ -72,7 +73,7 @@
         restorationTester.setContent {
             for (i in 0..1) {
                 key(i) {
-                    states[i] = savedInstanceState { 0 }
+                    states[i] = rememberSaveable { mutableStateOf(0) }
                 }
             }
         }
@@ -133,9 +134,9 @@
         var stateOutside: MutableState<String>? = null
         restorationTester.setContent {
             repeat(number) {
-                statesInLoop[it] = savedInstanceState { 0 }
+                statesInLoop[it] = rememberSaveable { mutableStateOf(0) }
             }
-            stateOutside = savedInstanceState { "0" }
+            stateOutside = rememberSaveable { mutableStateOf("0") }
         }
 
         rule.runOnIdle {
@@ -158,8 +159,8 @@
     fun twoStates() {
         val states = arrayOfNulls<MutableState<Int>>(2)
         restorationTester.setContent {
-            states[0] = savedInstanceState { 0 }
-            states[1] = savedInstanceState { 0 }
+            states[0] = rememberSaveable { mutableStateOf(0) }
+            states[1] = rememberSaveable { mutableStateOf(0) }
         }
 
         rule.runOnUiThread {
@@ -188,9 +189,9 @@
         val states = arrayOfNulls<MutableState<Int>>(2)
         restorationTester.setContent {
             if (needFirst) {
-                states[0] = savedInstanceState { 0 }
+                states[0] = rememberSaveable { mutableStateOf(0) }
             }
-            states[1] = savedInstanceState { 0 }
+            states[1] = rememberSaveable { mutableStateOf(0) }
         }
 
         rule.runOnUiThread {
@@ -276,6 +277,6 @@
 
     @Composable
     fun FunctionWithState(states: Array<MutableState<Int>?>, index: Int) {
-        states[index] = savedInstanceState { 0 }
+        states[index] = rememberSaveable { mutableStateOf(0) }
     }
 }
diff --git a/compose/runtime/runtime-saveable/src/commonMain/kotlin/androidx/compose/runtime/saveable/ListSaver.kt b/compose/runtime/runtime-saveable/src/commonMain/kotlin/androidx/compose/runtime/saveable/ListSaver.kt
index 149d147..c4fd30e 100644
--- a/compose/runtime/runtime-saveable/src/commonMain/kotlin/androidx/compose/runtime/saveable/ListSaver.kt
+++ b/compose/runtime/runtime-saveable/src/commonMain/kotlin/androidx/compose/runtime/saveable/ListSaver.kt
@@ -23,7 +23,7 @@
  * What types can be saved is defined by [SaveableStateRegistry], by default everything which can
  * be stored in the Bundle class can be saved.
  *
- * You can use it as a parameter for [savedInstanceState] or [rememberSaveable].
+ * You can use it as a parameter for [rememberSaveable].
  *
  * @sample androidx.compose.runtime.saveable.samples.ListSaverSample
  */
diff --git a/compose/runtime/runtime-saveable/src/commonMain/kotlin/androidx/compose/runtime/saveable/MapSaver.kt b/compose/runtime/runtime-saveable/src/commonMain/kotlin/androidx/compose/runtime/saveable/MapSaver.kt
index 9c7c2f1..6ad0912 100644
--- a/compose/runtime/runtime-saveable/src/commonMain/kotlin/androidx/compose/runtime/saveable/MapSaver.kt
+++ b/compose/runtime/runtime-saveable/src/commonMain/kotlin/androidx/compose/runtime/saveable/MapSaver.kt
@@ -23,7 +23,7 @@
  * What types can be saved is defined by [SaveableStateRegistry], by default everything which can
  * be stored in the Bundle class can be saved.
  *
- * You can use it as a parameter for [savedInstanceState] or [rememberSaveable].
+ * You can use it as a parameter for [rememberSaveable].
  *
  * @sample androidx.compose.runtime.saveable.samples.MapSaverSample
  */
diff --git a/compose/runtime/runtime-saveable/src/commonMain/kotlin/androidx/compose/runtime/saveable/RememberSaveable.kt b/compose/runtime/runtime-saveable/src/commonMain/kotlin/androidx/compose/runtime/saveable/RememberSaveable.kt
index fa0fe95..2f53714 100644
--- a/compose/runtime/runtime-saveable/src/commonMain/kotlin/androidx/compose/runtime/saveable/RememberSaveable.kt
+++ b/compose/runtime/runtime-saveable/src/commonMain/kotlin/androidx/compose/runtime/saveable/RememberSaveable.kt
@@ -19,9 +19,14 @@
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.DisposableEffect
 import androidx.compose.runtime.MutableState
+import androidx.compose.runtime.SnapshotMutationPolicy
 import androidx.compose.runtime.currentCompositeKeyHash
 import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.neverEqualPolicy
+import androidx.compose.runtime.referentialEqualityPolicy
 import androidx.compose.runtime.remember
+import androidx.compose.runtime.snapshots.SnapshotMutableState
+import androidx.compose.runtime.structuralEqualityPolicy
 
 /**
  * Remember the value produced by [init].
@@ -32,15 +37,21 @@
  *
  * @sample androidx.compose.runtime.saveable.samples.RememberSaveable
  *
- * This function works nicely with mutable objects, when you update the state of this object
- * instead of recreating it. If you work with immutable objects [savedInstanceState] can suit you
- * more as it wraps the value into the [MutableState].
- *
  * If you use it with types which can be stored inside the Bundle then it will be saved and
  * restored automatically using [autoSaver], otherwise you will need to provide a custom [Saver]
  * implementation via the [saver] param.
  *
- * @sample androidx.compose.runtime.saveable.samples.CustomSaverSample
+ * @sample androidx.compose.runtime.saveable.samples.RememberSaveableCustomSaver
+ *
+ * You can use it with a value stored inside [androidx.compose.runtime.mutableStateOf].
+ *
+ * @sample androidx.compose.runtime.saveable.samples.RememberSaveableWithMutableState
+ *
+ * If the value inside the MutableState can be stored inside the Bundle it would be saved
+ * and restored automatically, otherwise you will need to provide a custom [Saver]
+ * implementation via an overload with which has `stateSaver` param.
+ *
+ * @sample androidx.compose.runtime.saveable.samples.RememberSaveableWithMutableStateAndCustomSaver
  *
  * @param inputs A set of inputs such that, when any of them have changed, will cause the state to
  * reset and [init] to be rerun
@@ -98,16 +109,82 @@
     return value
 }
 
+/**
+ * Remember the value produced by [init].
+ *
+ * It behaves similarly to [remember], but the stored value will survive the activity or process
+ * recreation using the saved instance state mechanism (for example it happens when the screen is
+ * rotated in the Android application).
+ *
+ * Use this overload if you remember a mutable state with a type which can't be stored in the
+ * Bundle so you have to provide a custom saver object.
+ *
+ * @sample androidx.compose.runtime.saveable.samples.RememberSaveableWithMutableStateAndCustomSaver
+ *
+ * @param inputs A set of inputs such that, when any of them have changed, will cause the state to
+ * reset and [init] to be rerun
+ * @param stateSaver The [Saver] object which defines how the value inside the MutableState is
+ * saved and restored.
+ * @param key An optional key to be used as a key for the saved value. If not provided we use the
+ * automatically generated by the Compose runtime which is unique for the every exact code location
+ * in the composition tree
+ * @param init A factory function to create the initial value of this state
+ */
+@Composable
+fun <T> rememberSaveable(
+    vararg inputs: Any?,
+    stateSaver: Saver<T, out Any>,
+    key: String? = null,
+    init: () -> MutableState<T>
+): MutableState<T> = rememberSaveable(
+    inputs,
+    saver = mutableStateSaver(stateSaver),
+    key = key,
+    init = init
+)
+
+@Suppress("UNCHECKED_CAST")
+private fun <T> mutableStateSaver(inner: Saver<T, out Any>) = with(inner as Saver<T, Any>) {
+    Saver<MutableState<T>, MutableState<Any?>>(
+        save = { state ->
+            require(state is SnapshotMutableState<T>) {
+                "If you use a custom MutableState implementation you have to write a custom " +
+                    "Saver and pass it as a saver param to rememberSaveable()"
+            }
+            mutableStateOf(save(state.value), state.policy as SnapshotMutationPolicy<Any?>)
+        },
+        restore = @Suppress("UNCHECKED_CAST") {
+            require(it is SnapshotMutableState<Any?>)
+            mutableStateOf(
+                if (it.value != null) restore(it.value!!) else null,
+                it.policy as SnapshotMutationPolicy<T?>
+            ) as MutableState<T>
+        }
+    )
+}
+
 private fun SaveableStateRegistry.requireCanBeSaved(value: Any?) {
     if (value != null && !canBeSaved(value)) {
         throw IllegalArgumentException(
-            if (value is MutableState<*>) {
-                "Please use savedInstanceState() if you want to save a MutableState"
+            if (value is SnapshotMutableState<*>) {
+                if (value.policy !== neverEqualPolicy<Any?>() &&
+                    value.policy !== structuralEqualityPolicy<Any?>() &&
+                    value.policy !== referentialEqualityPolicy<Any?>()
+                ) {
+                    "If you use a custom SnapshotMutationPolicy for your MutableState you have to" +
+                        " write a custom Saver"
+                } else {
+                    "MutableState containing ${value.value} cannot be saved using the current " +
+                        "SaveableStateRegistry. The default implementation only supports types " +
+                        "which can be stored inside the Bundle. Please consider implementing a " +
+                        "custom Saver for this class and pass it as a stateSaver parameter to " +
+                        "rememberSaveable()."
+                }
             } else {
-                "$value cannot be saved using the current UiSavedStateRegistry. The default " +
+                "$value cannot be saved using the current SaveableStateRegistry. The default " +
                     "implementation only supports types which can be stored inside the Bundle" +
                     ". Please consider implementing a custom Saver for this class and pass it" +
-                    " to savedInstanceState() or rememberSaveable()."
+                    " to rememberSaveable()."
             }
         )
     }
diff --git a/compose/runtime/runtime-saveable/src/commonMain/kotlin/androidx/compose/runtime/saveable/SaveableStateHolder.kt b/compose/runtime/runtime-saveable/src/commonMain/kotlin/androidx/compose/runtime/saveable/SaveableStateHolder.kt
index 7f8cdcd..3c24c63 100644
--- a/compose/runtime/runtime-saveable/src/commonMain/kotlin/androidx/compose/runtime/saveable/SaveableStateHolder.kt
+++ b/compose/runtime/runtime-saveable/src/commonMain/kotlin/androidx/compose/runtime/saveable/SaveableStateHolder.kt
@@ -24,10 +24,10 @@
 import androidx.compose.runtime.remember
 
 /**
- * Allows to save the state defined with [savedInstanceState] and [rememberSaveable]
- * for the subtree before disposing it to make it possible to compose it back next time with the
- * restored state. It allows different navigation patterns to keep the ui state like scroll
- * position for the currently not composed screens from the backstack.
+ * Allows to save the state defined with [rememberSaveable] for the subtree before disposing it
+ * to make it possible to compose it back next time with the restored state. It allows different
+ * navigation patterns to keep the ui state like scroll position for the currently not composed
+ * screens from the backstack.
  *
  * @sample androidx.compose.runtime.saveable.samples.SimpleNavigationWithSaveableStateSample
  *
@@ -38,9 +38,8 @@
 interface SaveableStateHolder {
     /**
      * Put your content associated with a [key] inside the [content]. This will automatically
-     * save all the states defined with [savedInstanceState] and [rememberSaveable]
-     * before disposing the content and will restore the states when you compose with this key
-     * again.
+     * save all the states defined with [rememberSaveable] before disposing the content and will
+     * restore the states when you compose with this key again.
      *
      * @param key to be used for saving and restoring the states for the subtree. Note that on
      * Android you can only use types which can be stored inside the Bundle.
diff --git a/compose/runtime/runtime-saveable/src/commonMain/kotlin/androidx/compose/runtime/saveable/Saver.kt b/compose/runtime/runtime-saveable/src/commonMain/kotlin/androidx/compose/runtime/saveable/Saver.kt
index 26d48ee..9d98db9 100644
--- a/compose/runtime/runtime-saveable/src/commonMain/kotlin/androidx/compose/runtime/saveable/Saver.kt
+++ b/compose/runtime/runtime-saveable/src/commonMain/kotlin/androidx/compose/runtime/saveable/Saver.kt
@@ -24,8 +24,7 @@
  * be stored in the Bundle class can be saved.
  * The implementations can check that the provided value can be saved via [SaverScope.canBeSaved]
  *
- * You can pass the implementations of this class as a parameter for [savedInstanceState] or
- * [rememberSaveable].
+ * You can pass the implementations of this class as a parameter for [rememberSaveable].
  *
  * @sample androidx.compose.runtime.saveable.samples.CustomSaverSample
  */
@@ -50,8 +49,7 @@
  * be stored in the Bundle class can be saved.
  * The implementations can check that the provided value can be saved via [SaverScope.canBeSaved]
  *
- * You can pass the implementations of this class as a parameter for [savedInstanceState] or
- * [rememberSaveable].
+ * You can pass the implementations of this class as a parameter for [rememberSaveable].
  *
  * @sample androidx.compose.runtime.saveable.samples.CustomSaverSample
  *
@@ -87,7 +85,7 @@
 /**
  * The default implementation of [Saver] which does not perform any conversion.
  *
- * It is used by [savedInstanceState] and [rememberSaveable] by default.
+ * It is used by [rememberSaveable] by default.
  *
  * @see Saver
  */
diff --git a/compose/runtime/runtime-saveable/src/commonMain/kotlin/androidx/compose/runtime/savedinstancestate/Deprecated.kt b/compose/runtime/runtime-saveable/src/commonMain/kotlin/androidx/compose/runtime/savedinstancestate/Deprecated.kt
index 74609a3..43e210f 100644
--- a/compose/runtime/runtime-saveable/src/commonMain/kotlin/androidx/compose/runtime/savedinstancestate/Deprecated.kt
+++ b/compose/runtime/runtime-saveable/src/commonMain/kotlin/androidx/compose/runtime/savedinstancestate/Deprecated.kt
@@ -21,6 +21,7 @@
 package androidx.compose.runtime.savedinstancestate
 
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.MutableState
 import androidx.compose.runtime.saveable.SaveableStateRegistry
 import androidx.compose.runtime.staticAmbientOf
 
@@ -174,3 +175,63 @@
             " package"
     )
 }
+
+@Deprecated(
+    "It was removed in favor or using rememberSaveable { mutableStateOf(value) }. If you used it " +
+        "with a custom saver you can now pass it like this: rememberSaveable(stateSaver = " +
+        "MySaver) { mutableStateOf(value) }",
+    ReplaceWith(
+        "rememberSaveable { mutableStateOf(init()) }",
+        "androidx.compose.runtime.saveable.rememberSaveable",
+        "androidx.compose.runtime.mutableStateOf"
+    ),
+    level = DeprecationLevel.ERROR
+)
+@Suppress("DocumentExceptions")
+@Composable
+fun <T> savedInstanceState(
+    key: String? = null,
+    init: () -> T
+): MutableState<T> = throw IllegalStateException(
+    "It was removed in favor or using rememberSaveable { mutableStateOf(value) }"
+)
+
+@Deprecated(
+    "It was removed in favor or using rememberSaveable(stateSaver = MySaver) { mutableStateOf" +
+        "(value) }",
+    ReplaceWith(
+        "rememberSaveable(stateSaver = saver) { mutableStateOf(init()) }",
+        "androidx.compose.runtime.saveable.rememberSaveable",
+        "androidx.compose.runtime.mutableStateOf"
+    ),
+    level = DeprecationLevel.ERROR
+)
+@Suppress("DocumentExceptions")
+@Composable
+fun <T> savedInstanceState(
+    saver: Saver<T, out Any>,
+    key: String? = null,
+    init: () -> T
+): MutableState<T> = throw IllegalStateException(
+    "It was removed in favor or using rememberSaveable { mutableStateOf(value) }"
+)
+
+@Deprecated(
+    "It was removed in favor or using rememberSaveable(stateSaver = MySaver) { mutableStateOf" +
+        "(value) }",
+    ReplaceWith(
+        "rememberSaveable(stateSaver = saver) { mutableStateOf(init()) }",
+        "androidx.compose.runtime.saveable.rememberSaveable",
+        "androidx.compose.runtime.mutableStateOf"
+    ),
+    level = DeprecationLevel.ERROR
+)
+@Suppress("DocumentExceptions")
+@Composable
+fun <T> savedInstanceState(
+    saver: androidx.compose.runtime.saveable.Saver<T, out Any>,
+    key: String? = null,
+    init: () -> T
+): MutableState<T> = throw IllegalStateException(
+    "It was removed in favor or using rememberSaveable { mutableStateOf(value) }"
+)
diff --git a/compose/runtime/runtime-saveable/src/commonMain/kotlin/androidx/compose/runtime/savedinstancestate/SavedInstanceState.kt b/compose/runtime/runtime-saveable/src/commonMain/kotlin/androidx/compose/runtime/savedinstancestate/SavedInstanceState.kt
deleted file mode 100644
index be4afb1..0000000
--- a/compose/runtime/runtime-saveable/src/commonMain/kotlin/androidx/compose/runtime/savedinstancestate/SavedInstanceState.kt
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright 2020 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.compose.runtime.savedinstancestate
-
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.MutableState
-import androidx.compose.runtime.SnapshotMutationPolicy
-import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.structuralEqualityPolicy
-import androidx.compose.runtime.saveable.Saver
-import androidx.compose.runtime.saveable.autoSaver
-import androidx.compose.runtime.saveable.rememberSaveable
-
-/**
- * Used to introduce a state value of type [T] into a composition.
- *
- * It behaves similarly to `remember { mutableStateOf(...) }`, but the stored value will survive
- * the activity or process recreation using the saved instance state mechanism (for example it
- * happens when the screen is rotated in the Android application).
- *
- * @sample androidx.compose.runtime.savedinstancestate.samples.SavedInstanceStateSample
- *
- * This function works nicely with immutable values as we wrap them into [MutableState] and
- * update the values in this state. If you work with a mutable object and going to update the
- * state of this object instead of recreating it [rememberSaveable] can suit you more.
- *
- * If you use it with types which can be stored inside the Bundle then it will be saved and
- * restored automatically using [autoSaver], otherwise you will need to provide a custom [Saver]
- * implementation via the [saver] param.
- *
- * @sample androidx.compose.runtime.saveable.samples.CustomSaverSample
- *
- * @param inputs A set of inputs such that, when any of them have changed, will cause the state to
- * reset and [init] to be rerun
- * @param saver The [Saver] object which defines how the state is saved and restored.
- * @param key An optional key to be used as a key for the saved value. If not provided we use the
- * automatically generated by the Compose runtime which is unique for the every exact code location
- * in the composition tree
- * @param policy a callback to compare the previous and new instance of [T] when
- * [MutableState.value] is written to. The policy is used to determine how composition should be
- * scheduled. See [SnapshotMutationPolicy].
- * @param init A factory function to create the initial value of this state
- */
-@Composable
-fun <T> savedInstanceState(
-    vararg inputs: Any?,
-    saver: Saver<T, out Any> = autoSaver(),
-    key: String? = null,
-    policy: SnapshotMutationPolicy<T> = structuralEqualityPolicy(),
-    init: () -> T
-): MutableState<T> = rememberSaveable(
-    *inputs,
-    saver = mutableStateSaver(saver, policy),
-    key = key,
-    init = { mutableStateOf(init(), policy) }
-)
-
-private fun <T> mutableStateSaver(
-    inner: Saver<T, out Any>,
-    policy: SnapshotMutationPolicy<T>
-) = Saver<MutableState<T>, Any>(
-    save = { state ->
-        with(inner) {
-            val value = state.value
-            if (value == null) {
-                EmptyStateValue
-            } else {
-                save(value)
-            }
-        }
-    },
-    restore = @Suppress("UNCHECKED_CAST") {
-        val restored = if (it == EmptyStateValue) {
-            null
-        } else {
-            (inner as Saver<T, Any>).restore(it)
-        }
-        mutableStateOf(restored as T, policy)
-    }
-)
-
-/**
- * The object we save to indicate that we will need to restore the state with a null value.
- */
-private val EmptyStateValue = "[NullValuePlacedInsideTheMutableState]"
\ No newline at end of file
diff --git a/compose/ui/ui-test-junit4/src/androidMain/kotlin/androidx/compose/ui/test/junit4/StateRestorationTester.kt b/compose/ui/ui-test-junit4/src/androidMain/kotlin/androidx/compose/ui/test/junit4/StateRestorationTester.kt
index 90e1c1a..e49c1eb 100644
--- a/compose/ui/ui-test-junit4/src/androidMain/kotlin/androidx/compose/ui/test/junit4/StateRestorationTester.kt
+++ b/compose/ui/ui-test-junit4/src/androidMain/kotlin/androidx/compose/ui/test/junit4/StateRestorationTester.kt
@@ -33,7 +33,7 @@
  * [emulateSavedInstanceStateRestore] and assert your state is restored properly.
  *
  * Note that this tests only the restoration of the local state of the composable you passed to
- * [setContent] and useful for testing [savedInstanceState] or [rememberSaveable]
+ * [setContent] and useful for testing [androidx.compose.runtime.saveable.rememberSaveable]
  * integration. It is not testing the integration with any other life cycles or Activity callbacks.
  */
 class StateRestorationTester(private val composeTestRule: ComposeContentTestRule) {
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/DisposableSaveableStateRegistry.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/DisposableSaveableStateRegistry.kt
index c46566b..0c60a2c 100644
--- a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/DisposableSaveableStateRegistry.kt
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/DisposableSaveableStateRegistry.kt
@@ -16,14 +16,22 @@
 
 package androidx.compose.ui.platform
 
+import android.annotation.SuppressLint
 import android.os.Binder
 import android.os.Bundle
+import android.os.Parcel
 import android.os.Parcelable
 import android.util.Size
 import android.util.SizeF
 import android.util.SparseArray
 import android.view.View
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.neverEqualPolicy
+import androidx.compose.runtime.referentialEqualityPolicy
 import androidx.compose.runtime.saveable.SaveableStateRegistry
+import androidx.compose.runtime.snapshots.SnapshotMutableState
+import androidx.compose.runtime.structuralEqualityPolicy
+import androidx.compose.ui.util.fastForEachIndexed
 import androidx.savedstate.SavedStateRegistry
 import androidx.savedstate.SavedStateRegistryOwner
 import java.io.Serializable
@@ -113,6 +121,15 @@
             return true
         }
     }
+    if (value is SnapshotMutableState<*>) {
+        if (value.policy === neverEqualPolicy<Any?>() ||
+            value.policy === structuralEqualityPolicy<Any?>() ||
+            value.policy === referentialEqualityPolicy<Any?>()
+        ) {
+            val stateValue = value.value
+            return if (stateValue == null) true else canBeSavedToBundle(stateValue)
+        }
+    }
     return false
 }
 
@@ -145,7 +162,14 @@
 private fun Bundle.toMap(): Map<String, List<Any?>>? {
     val map = mutableMapOf<String, List<Any?>>()
     this.keySet().forEach { key ->
-        map[key] = getParcelableArrayList<Parcelable?>(key) as List<Any?>
+        @Suppress("UNCHECKED_CAST")
+        val list = getParcelableArrayList<Parcelable?>(key) as ArrayList<Any?>
+        list.fastForEachIndexed { index, value ->
+            if (value is ParcelableMutableStateHolder) {
+                list[index] = value.state
+            }
+        }
+        map[key] = list
     }
     return map
 }
@@ -153,7 +177,12 @@
 private fun Map<String, List<Any?>>.toBundle(): Bundle {
     val bundle = Bundle()
     forEach { (key, list) ->
-        val arrayList = if (list is ArrayList<*>) list else ArrayList(list)
+        val arrayList = if (list is ArrayList<Any?>) list else ArrayList(list)
+        arrayList.fastForEachIndexed { index, value ->
+            if (value is SnapshotMutableState<*>) {
+                arrayList[index] = ParcelableMutableStateHolder(value)
+            }
+        }
         @Suppress("UNCHECKED_CAST")
         bundle.putParcelableArrayList(
             key,
@@ -162,3 +191,66 @@
     }
     return bundle
 }
+
+@SuppressLint("BanParcelableUsage")
+private class ParcelableMutableStateHolder : Parcelable {
+
+    val state: SnapshotMutableState<*>
+
+    constructor(state: SnapshotMutableState<*>) {
+        this.state = state
+    }
+
+    private constructor(parcel: Parcel, loader: ClassLoader?) {
+        val value = parcel.readValue(loader ?: javaClass.classLoader)
+        val policyIndex = parcel.readInt()
+        state = mutableStateOf(
+            value,
+            when (policyIndex) {
+                PolicyNeverEquals -> neverEqualPolicy()
+                PolicyStructuralEquality -> structuralEqualityPolicy()
+                PolicyReferentialEquality -> referentialEqualityPolicy()
+                else -> throw IllegalStateException(
+                    "Restored an incorrect MutableState policy $policyIndex"
+                )
+            }
+        ) as SnapshotMutableState
+    }
+
+    override fun writeToParcel(parcel: Parcel, flags: Int) {
+        parcel.writeValue(state.value)
+        parcel.writeInt(
+            when (state.policy) {
+                neverEqualPolicy<Any?>() -> PolicyNeverEquals
+                structuralEqualityPolicy<Any?>() -> PolicyStructuralEquality
+                referentialEqualityPolicy<Any?>() -> PolicyReferentialEquality
+                else -> throw IllegalStateException(
+                    "Only known types of MutableState's SnapshotMutationPolicy are supported"
+                )
+            }
+        )
+    }
+
+    override fun describeContents(): Int {
+        return 0
+    }
+
+    companion object {
+        private const val PolicyNeverEquals = 0
+        private const val PolicyStructuralEquality = 1
+        private const val PolicyReferentialEquality = 2
+
+        @Suppress("unused")
+        @JvmField
+        val CREATOR: Parcelable.Creator<ParcelableMutableStateHolder> =
+            object : Parcelable.ClassLoaderCreator<ParcelableMutableStateHolder> {
+                override fun createFromParcel(parcel: Parcel, loader: ClassLoader) =
+                    ParcelableMutableStateHolder(parcel, loader)
+
+                override fun createFromParcel(parcel: Parcel) =
+                    ParcelableMutableStateHolder(parcel, null)
+
+                override fun newArray(size: Int) = arrayOfNulls<ParcelableMutableStateHolder?>(size)
+            }
+    }
+}
diff --git a/navigation/navigation-compose/integration-tests/navigation-demos/src/main/java/androidx/navigation/compose/demos/NavByDeepLinkDemo.kt b/navigation/navigation-compose/integration-tests/navigation-demos/src/main/java/androidx/navigation/compose/demos/NavByDeepLinkDemo.kt
index e0469ed..c5deef4 100644
--- a/navigation/navigation-compose/integration-tests/navigation-demos/src/main/java/androidx/navigation/compose/demos/NavByDeepLinkDemo.kt
+++ b/navigation/navigation-compose/integration-tests/navigation-demos/src/main/java/androidx/navigation/compose/demos/NavByDeepLinkDemo.kt
@@ -28,7 +28,8 @@
 import androidx.compose.material.Text
 import androidx.compose.material.TextField
 import androidx.compose.runtime.Composable
-import androidx.compose.runtime.savedinstancestate.savedInstanceState
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.saveable.rememberSaveable
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.res.stringResource
@@ -63,7 +64,7 @@
     Column(Modifier.fillMaxSize().then(Modifier.padding(8.dp))) {
         Text(text = stringResource(Screen.Profile.resourceId))
         Divider(color = Color.Black)
-        val state = savedInstanceState { "" }
+        val state = rememberSaveable { mutableStateOf("") }
         Box {
             TextField(
                 value = state.value,
diff --git a/navigation/navigation-compose/integration-tests/navigation-demos/src/main/java/androidx/navigation/compose/demos/NavSingleTopDemo.kt b/navigation/navigation-compose/integration-tests/navigation-demos/src/main/java/androidx/navigation/compose/demos/NavSingleTopDemo.kt
index 20021f3..0cc7bcb 100644
--- a/navigation/navigation-compose/integration-tests/navigation-demos/src/main/java/androidx/navigation/compose/demos/NavSingleTopDemo.kt
+++ b/navigation/navigation-compose/integration-tests/navigation-demos/src/main/java/androidx/navigation/compose/demos/NavSingleTopDemo.kt
@@ -23,7 +23,8 @@
 import androidx.compose.material.Text
 import androidx.compose.material.TextField
 import androidx.compose.runtime.Composable
-import androidx.compose.runtime.savedinstancestate.savedInstanceState
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.saveable.rememberSaveable
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.unit.dp
@@ -36,7 +37,7 @@
 @Composable
 fun NavSingleTopDemo() {
     val navController = rememberNavController()
-    val query = savedInstanceState { "" }
+    val query = rememberSaveable { mutableStateOf("") }
     Column(Modifier.fillMaxSize().then(Modifier.padding(8.dp))) {
         TextField(
             value = query.value,
diff --git a/navigation/navigation-compose/integration-tests/navigation-demos/src/main/java/androidx/navigation/compose/demos/NavWithArgsDemo.kt b/navigation/navigation-compose/integration-tests/navigation-demos/src/main/java/androidx/navigation/compose/demos/NavWithArgsDemo.kt
index 0197207..e5253fb 100644
--- a/navigation/navigation-compose/integration-tests/navigation-demos/src/main/java/androidx/navigation/compose/demos/NavWithArgsDemo.kt
+++ b/navigation/navigation-compose/integration-tests/navigation-demos/src/main/java/androidx/navigation/compose/demos/NavWithArgsDemo.kt
@@ -24,7 +24,8 @@
 import androidx.compose.material.Text
 import androidx.compose.material.TextField
 import androidx.compose.runtime.Composable
-import androidx.compose.runtime.savedinstancestate.savedInstanceState
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.saveable.rememberSaveable
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.res.stringResource
@@ -54,7 +55,7 @@
     Column(Modifier.fillMaxSize().then(Modifier.padding(8.dp))) {
         Text(text = stringResource(Screen.Profile.resourceId))
         Divider(color = Color.Black)
-        val state = savedInstanceState { "" }
+        val state = rememberSaveable { mutableStateOf("") }
         Box {
             TextField(
                 value = state.value,