Merge "Run ./gradlew updateAbi" into androidx-main
diff --git a/lifecycle/lifecycle-viewmodel/api/current.txt b/lifecycle/lifecycle-viewmodel/api/current.txt
index f4d093f..7181574 100644
--- a/lifecycle/lifecycle-viewmodel/api/current.txt
+++ b/lifecycle/lifecycle-viewmodel/api/current.txt
@@ -124,6 +124,11 @@
 
   public abstract class CreationExtras {
     method public abstract operator <T> T? get(androidx.lifecycle.viewmodel.CreationExtras.Key<T> key);
+    field public static final androidx.lifecycle.viewmodel.CreationExtras.Companion Companion;
+  }
+
+  public static final class CreationExtras.Companion {
+    method public inline <reified T> androidx.lifecycle.viewmodel.CreationExtras.Key<T> Key();
   }
 
   public static final class CreationExtras.Empty extends androidx.lifecycle.viewmodel.CreationExtras {
@@ -134,6 +139,12 @@
   public static interface CreationExtras.Key<T> {
   }
 
+  public final class CreationExtrasKt {
+    method public static operator boolean contains(androidx.lifecycle.viewmodel.CreationExtras, androidx.lifecycle.viewmodel.CreationExtras.Key<? extends java.lang.Object?> key);
+    method public static operator androidx.lifecycle.viewmodel.MutableCreationExtras plus(androidx.lifecycle.viewmodel.CreationExtras, androidx.lifecycle.viewmodel.CreationExtras creationExtras);
+    method public static operator void plusAssign(androidx.lifecycle.viewmodel.MutableCreationExtras, androidx.lifecycle.viewmodel.CreationExtras creationExtras);
+  }
+
   @androidx.lifecycle.viewmodel.ViewModelFactoryDsl public final class InitializerViewModelFactoryBuilder {
     ctor public InitializerViewModelFactoryBuilder();
     method public <T extends androidx.lifecycle.ViewModel> void addInitializer(kotlin.reflect.KClass<T> clazz, kotlin.jvm.functions.Function1<? super androidx.lifecycle.viewmodel.CreationExtras,? extends T> initializer);
@@ -146,6 +157,7 @@
   }
 
   public final class MutableCreationExtras extends androidx.lifecycle.viewmodel.CreationExtras {
+    ctor public MutableCreationExtras();
     ctor public MutableCreationExtras(optional androidx.lifecycle.viewmodel.CreationExtras initialExtras);
     method public <T> T? get(androidx.lifecycle.viewmodel.CreationExtras.Key<T> key);
     method public operator <T> void set(androidx.lifecycle.viewmodel.CreationExtras.Key<T> key, T t);
diff --git a/lifecycle/lifecycle-viewmodel/api/restricted_current.txt b/lifecycle/lifecycle-viewmodel/api/restricted_current.txt
index f4d093f..7181574 100644
--- a/lifecycle/lifecycle-viewmodel/api/restricted_current.txt
+++ b/lifecycle/lifecycle-viewmodel/api/restricted_current.txt
@@ -124,6 +124,11 @@
 
   public abstract class CreationExtras {
     method public abstract operator <T> T? get(androidx.lifecycle.viewmodel.CreationExtras.Key<T> key);
+    field public static final androidx.lifecycle.viewmodel.CreationExtras.Companion Companion;
+  }
+
+  public static final class CreationExtras.Companion {
+    method public inline <reified T> androidx.lifecycle.viewmodel.CreationExtras.Key<T> Key();
   }
 
   public static final class CreationExtras.Empty extends androidx.lifecycle.viewmodel.CreationExtras {
@@ -134,6 +139,12 @@
   public static interface CreationExtras.Key<T> {
   }
 
+  public final class CreationExtrasKt {
+    method public static operator boolean contains(androidx.lifecycle.viewmodel.CreationExtras, androidx.lifecycle.viewmodel.CreationExtras.Key<? extends java.lang.Object?> key);
+    method public static operator androidx.lifecycle.viewmodel.MutableCreationExtras plus(androidx.lifecycle.viewmodel.CreationExtras, androidx.lifecycle.viewmodel.CreationExtras creationExtras);
+    method public static operator void plusAssign(androidx.lifecycle.viewmodel.MutableCreationExtras, androidx.lifecycle.viewmodel.CreationExtras creationExtras);
+  }
+
   @androidx.lifecycle.viewmodel.ViewModelFactoryDsl public final class InitializerViewModelFactoryBuilder {
     ctor public InitializerViewModelFactoryBuilder();
     method public <T extends androidx.lifecycle.ViewModel> void addInitializer(kotlin.reflect.KClass<T> clazz, kotlin.jvm.functions.Function1<? super androidx.lifecycle.viewmodel.CreationExtras,? extends T> initializer);
@@ -146,6 +157,7 @@
   }
 
   public final class MutableCreationExtras extends androidx.lifecycle.viewmodel.CreationExtras {
+    ctor public MutableCreationExtras();
     ctor public MutableCreationExtras(optional androidx.lifecycle.viewmodel.CreationExtras initialExtras);
     method public <T> T? get(androidx.lifecycle.viewmodel.CreationExtras.Key<T> key);
     method public operator <T> void set(androidx.lifecycle.viewmodel.CreationExtras.Key<T> key, T t);
diff --git a/lifecycle/lifecycle-viewmodel/bcv/native/current.txt b/lifecycle/lifecycle-viewmodel/bcv/native/current.txt
index 6570006..c22e7d4 100644
--- a/lifecycle/lifecycle-viewmodel/bcv/native/current.txt
+++ b/lifecycle/lifecycle-viewmodel/bcv/native/current.txt
@@ -9,9 +9,15 @@
 abstract class androidx.lifecycle.viewmodel/CreationExtras { // androidx.lifecycle.viewmodel/CreationExtras|null[0]
     abstract fun <#A1: kotlin/Any?> get(androidx.lifecycle.viewmodel/CreationExtras.Key<#A1>): #A1? // androidx.lifecycle.viewmodel/CreationExtras.get|get(androidx.lifecycle.viewmodel.CreationExtras.Key<0:0>){0§<kotlin.Any?>}[0]
     abstract interface <#A1: kotlin/Any?> Key // androidx.lifecycle.viewmodel/CreationExtras.Key|null[0]
+    final object Companion { // androidx.lifecycle.viewmodel/CreationExtras.Companion|null[0]
+        final inline fun <#A2: reified kotlin/Any?> Key(): androidx.lifecycle.viewmodel/CreationExtras.Key<#A2> // androidx.lifecycle.viewmodel/CreationExtras.Companion.Key|Key(){0§<kotlin.Any?>}[0]
+    }
     final object Empty : androidx.lifecycle.viewmodel/CreationExtras { // androidx.lifecycle.viewmodel/CreationExtras.Empty|null[0]
         final fun <#A2: kotlin/Any?> get(androidx.lifecycle.viewmodel/CreationExtras.Key<#A2>): #A2? // androidx.lifecycle.viewmodel/CreationExtras.Empty.get|get(androidx.lifecycle.viewmodel.CreationExtras.Key<0:0>){0§<kotlin.Any?>}[0]
     }
+    open fun equals(kotlin/Any?): kotlin/Boolean // androidx.lifecycle.viewmodel/CreationExtras.equals|equals(kotlin.Any?){}[0]
+    open fun hashCode(): kotlin/Int // androidx.lifecycle.viewmodel/CreationExtras.hashCode|hashCode(){}[0]
+    open fun toString(): kotlin/String // androidx.lifecycle.viewmodel/CreationExtras.toString|toString(){}[0]
 }
 abstract class androidx.lifecycle/ViewModel { // androidx.lifecycle/ViewModel|null[0]
     constructor <init>() // androidx.lifecycle/ViewModel.<init>|<init>(){}[0]
@@ -69,6 +75,9 @@
         open fun onRequery(androidx.lifecycle/ViewModel) // androidx.lifecycle/ViewModelProvider.OnRequeryFactory.onRequery|onRequery(androidx.lifecycle.ViewModel){}[0]
     }
 }
+final fun (androidx.lifecycle.viewmodel/CreationExtras).androidx.lifecycle.viewmodel/contains(androidx.lifecycle.viewmodel/CreationExtras.Key<*>): kotlin/Boolean // androidx.lifecycle.viewmodel/contains|[email protected](androidx.lifecycle.viewmodel.CreationExtras.Key<*>){}[0]
+final fun (androidx.lifecycle.viewmodel/CreationExtras).androidx.lifecycle.viewmodel/plus(androidx.lifecycle.viewmodel/CreationExtras): androidx.lifecycle.viewmodel/MutableCreationExtras // androidx.lifecycle.viewmodel/plus|[email protected](androidx.lifecycle.viewmodel.CreationExtras){}[0]
+final fun (androidx.lifecycle.viewmodel/MutableCreationExtras).androidx.lifecycle.viewmodel/plusAssign(androidx.lifecycle.viewmodel/CreationExtras) // androidx.lifecycle.viewmodel/plusAssign|[email protected](androidx.lifecycle.viewmodel.CreationExtras){}[0]
 final inline fun <#A: reified androidx.lifecycle/ViewModel> (androidx.lifecycle.viewmodel/InitializerViewModelFactoryBuilder).androidx.lifecycle.viewmodel/initializer(noinline kotlin/Function1<androidx.lifecycle.viewmodel/CreationExtras, #A>) // androidx.lifecycle.viewmodel/initializer|initializer@androidx.lifecycle.viewmodel.InitializerViewModelFactoryBuilder(kotlin.Function1<androidx.lifecycle.viewmodel.CreationExtras,0:0>){0§<androidx.lifecycle.ViewModel>}[0]
 final inline fun <#A: reified androidx.lifecycle/ViewModel> (androidx.lifecycle/ViewModelProvider).androidx.lifecycle/get(): #A // androidx.lifecycle/get|[email protected](){0§<androidx.lifecycle.ViewModel>}[0]
 final inline fun androidx.lifecycle.viewmodel/viewModelFactory(kotlin/Function1<androidx.lifecycle.viewmodel/InitializerViewModelFactoryBuilder, kotlin/Unit>): androidx.lifecycle/ViewModelProvider.Factory // androidx.lifecycle.viewmodel/viewModelFactory|viewModelFactory(kotlin.Function1<androidx.lifecycle.viewmodel.InitializerViewModelFactoryBuilder,kotlin.Unit>){}[0]
diff --git a/lifecycle/lifecycle-viewmodel/src/androidInstrumentedTest/kotlin/androidx/lifecycle/CreationExtrasTest.kt b/lifecycle/lifecycle-viewmodel/src/androidInstrumentedTest/kotlin/androidx/lifecycle/CreationExtrasTest.kt
index ef58257..f64b119 100644
--- a/lifecycle/lifecycle-viewmodel/src/androidInstrumentedTest/kotlin/androidx/lifecycle/CreationExtrasTest.kt
+++ b/lifecycle/lifecycle-viewmodel/src/androidInstrumentedTest/kotlin/androidx/lifecycle/CreationExtrasTest.kt
@@ -16,26 +16,115 @@
 
 package androidx.lifecycle
 
-import android.os.Bundle
-import androidx.core.os.bundleOf
 import androidx.kruth.assertThat
 import androidx.lifecycle.viewmodel.CreationExtras
 import androidx.lifecycle.viewmodel.MutableCreationExtras
+import androidx.lifecycle.viewmodel.contains
+import androidx.lifecycle.viewmodel.plus
+import androidx.lifecycle.viewmodel.plusAssign
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import org.junit.Test
 import org.junit.runner.RunWith
 
+private val STRING_KEY_1 = CreationExtras.Key<String>()
+private val STRING_KEY_2 = CreationExtras.Key<String>()
+
 @RunWith(AndroidJUnit4::class)
 @SmallTest
 class CreationExtrasTest {
+
     @Test
-    fun testInitialCreationExtras() {
-        val initial = MutableCreationExtras()
-        val key = object : CreationExtras.Key<Bundle> {}
-        initial[key] = bundleOf("value" to "initial")
-        val mutable = MutableCreationExtras(initial)
-        initial[key] = bundleOf("value" to "overridden")
-        assertThat(mutable[key]?.getString("value")).isEqualTo("initial")
+    fun keyFactory_returnsDistinctInstances() {
+        val key1 = CreationExtras.Key<String>()
+        val key2 = CreationExtras.Key<String>()
+
+        assertThat(key1).isNotEqualTo(key2)
+    }
+
+    @Test
+    fun initialExtras_originalModifiedAfterCopy_copyRemainsUnchanged() {
+        val otherExtras = MutableCreationExtras().apply { this[STRING_KEY_1] = "value1" }
+        val underTest = MutableCreationExtras(initialExtras = otherExtras)
+        otherExtras[STRING_KEY_1] = "value2"
+
+        assertThat(otherExtras[STRING_KEY_1]).isEqualTo("value2")
+        assertThat(underTest[STRING_KEY_1]).isEqualTo("value1")
+    }
+
+    @Test
+    fun equals_sameValues_isEqual() {
+        val underTest = MutableCreationExtras().apply { this[STRING_KEY_1] = "value1" }
+        val otherExtras = MutableCreationExtras().apply { this[STRING_KEY_1] = "value1" }
+
+        assertThat(underTest).isEqualTo(otherExtras)
+    }
+
+    @Test
+    fun equals_differentValues_isNotEqual() {
+        val underTest = MutableCreationExtras().apply { this[STRING_KEY_1] = "value1" }
+        val otherExtras = MutableCreationExtras().apply { this[STRING_KEY_1] = "value2" }
+
+        assertThat(underTest).isNotEqualTo(otherExtras)
+    }
+
+    @Test
+    fun contains_returnsTrueForExistingKey() {
+        val underTest = MutableCreationExtras().apply { this[STRING_KEY_1] = "value1" }
+
+        val result = STRING_KEY_1 in underTest
+
+        assertThat(result).isTrue()
+    }
+
+    @Test
+    fun contains_returnsFalseForNonExistingKey() {
+        val underTest = MutableCreationExtras().apply { this[STRING_KEY_1] = "value1" }
+
+        val result = STRING_KEY_2 in underTest
+
+        assertThat(result).isFalse()
+    }
+
+    @Test
+    fun plus_addedTogetherWithUniqueKeys_combinesValues() {
+        val extras1 = MutableCreationExtras().apply { this[STRING_KEY_1] = "value1" }
+        val extras2 = MutableCreationExtras().apply { this[STRING_KEY_2] = "value2" }
+
+        val underTest = extras1 + extras2
+
+        assertThat(underTest[STRING_KEY_1]).isEqualTo(extras1[STRING_KEY_1])
+        assertThat(underTest[STRING_KEY_2]).isEqualTo(extras2[STRING_KEY_2])
+    }
+
+    @Test
+    fun plus_addedTogetherWithConflictingKeys_overridesFirstValue() {
+        val extras1 = MutableCreationExtras().apply { this[STRING_KEY_1] = "value1" }
+        val extras2 = MutableCreationExtras().apply { this[STRING_KEY_1] = "value2" }
+
+        val underTest = extras1 + extras2
+
+        assertThat(underTest[STRING_KEY_1]).isEqualTo(extras2[STRING_KEY_1])
+    }
+
+    @Test
+    fun plusAssign_addedTogetherWithUniqueKeys_combinesValues() {
+        val underTest = MutableCreationExtras().apply { this[STRING_KEY_1] = "value1" }
+        val otherExtras = MutableCreationExtras().apply { this[STRING_KEY_2] = "value2" }
+
+        underTest += otherExtras
+
+        assertThat(underTest[STRING_KEY_1]).isEqualTo(underTest[STRING_KEY_1])
+        assertThat(underTest[STRING_KEY_2]).isEqualTo(otherExtras[STRING_KEY_2])
+    }
+
+    @Test
+    fun plusAssign_addedTogetherWithConflictingKeys_overridesFirstValue() {
+        val underTest = MutableCreationExtras().apply { this[STRING_KEY_1] = "value1" }
+        val otherExtras = MutableCreationExtras().apply { this[STRING_KEY_1] = "value2" }
+
+        underTest += otherExtras
+
+        assertThat(underTest[STRING_KEY_1]).isEqualTo(otherExtras[STRING_KEY_1])
     }
 }
diff --git a/lifecycle/lifecycle-viewmodel/src/commonMain/kotlin/androidx/lifecycle/viewmodel/CreationExtras.kt b/lifecycle/lifecycle-viewmodel/src/commonMain/kotlin/androidx/lifecycle/viewmodel/CreationExtras.kt
index 3592b35..f7dfc9e 100644
--- a/lifecycle/lifecycle-viewmodel/src/commonMain/kotlin/androidx/lifecycle/viewmodel/CreationExtras.kt
+++ b/lifecycle/lifecycle-viewmodel/src/commonMain/kotlin/androidx/lifecycle/viewmodel/CreationExtras.kt
@@ -15,45 +15,120 @@
  */
 package androidx.lifecycle.viewmodel
 
+import androidx.lifecycle.ViewModelProvider
+import androidx.lifecycle.ViewModelProvider.Factory
+import androidx.lifecycle.viewmodel.CreationExtras.Key
+import kotlin.jvm.JvmOverloads
+import kotlin.jvm.JvmStatic
+
 /**
- * Simple map-like object that passed in [ViewModelProvider.Factory.create] to provide an additional
- * information to a factory.
+ * A map-like object holding pairs of [CreationExtras.Key] and [Any], enabling efficient value
+ * retrieval for each key. Each key in [CreationExtras] is unique, storing only one value per key.
  *
- * It allows making `Factory` implementations stateless, which makes an injection of factories
- * easier because don't require all information be available at construction time.
+ * [CreationExtras] is used in [ViewModelProvider.Factory.create] to provide extra information to
+ * the [Factory]. This makes [Factory] implementations stateless, simplifying factory injection by
+ * not requiring all information at construction time.
+ *
+ * This abstract class supports read-only access; use [MutableCreationExtras] for read-write access.
  */
 public abstract class CreationExtras internal constructor() {
-    internal val map: MutableMap<Key<*>, Any?> = mutableMapOf()
+    internal val extras: MutableMap<Key<*>, Any?> = mutableMapOf()
 
-    /** Key for the elements of [CreationExtras]. [T] is a type of an element with this key. */
+    /**
+     * Key for the elements of [CreationExtras]. [T] represents the type of element associated with
+     * this key.
+     */
     public interface Key<T>
 
-    /** Returns an element associated with the given [key] */
+    /**
+     * Returns the value to which the specified [key] is associated, or null if this
+     * [CreationExtras] contains no mapping for the key.
+     */
     public abstract operator fun <T> get(key: Key<T>): T?
 
-    /** Empty [CreationExtras] */
+    /** Compares the specified object with this [CreationExtras] for equality. */
+    override fun equals(other: Any?): Boolean = other is CreationExtras && extras == other.extras
+
+    /** Returns the hash code value for this [CreationExtras]. */
+    override fun hashCode(): Int = extras.hashCode()
+
+    /**
+     * Returns a string representation of this [CreationExtras]. The string representation consists
+     * of a list of key-value mappings in the order returned by the [CreationExtras]'s iterator.
+     */
+    override fun toString(): String = "CreationExtras(extras=$extras)"
+
+    /** An empty read-only [CreationExtras]. */
     public object Empty : CreationExtras() {
         override fun <T> get(key: Key<T>): T? = null
     }
+
+    public companion object {
+        /** Returns an unique [Key] to be associated with an extra. */
+        @JvmStatic public inline fun <reified T> Key(): Key<T> = object : Key<T> {}
+    }
 }
 
 /**
- * Mutable implementation of [CreationExtras]
+ * A modifiable [CreationExtras] that holds pairs of [CreationExtras.Key] and [Any], allowing
+ * efficient value retrieval for each key.
  *
- * @param initialExtras extras that will be filled into the resulting MutableCreationExtras
+ * Each key in [CreationExtras] is unique, storing only one value per key.
+ *
+ * @see [CreationExtras]
  */
-public class MutableCreationExtras(initialExtras: CreationExtras = Empty) : CreationExtras() {
+public class MutableCreationExtras
+/**
+ * Constructs a [MutableCreationExtras] containing the elements of the specified `initialExtras`, in
+ * the order they are returned by the [Map]'s iterator.
+ */
+internal constructor(initialExtras: Map<Key<*>, Any?>) : CreationExtras() {
+
+    /**
+     * Constructs a [MutableCreationExtras] containing the elements of the specified
+     * [initialExtras], in the order they are returned by the [CreationExtras]'s iterator.
+     */
+    @JvmOverloads
+    public constructor(initialExtras: CreationExtras = Empty) : this(initialExtras.extras)
 
     init {
-        map.putAll(initialExtras.map)
+        extras += initialExtras
     }
 
-    /** Associates the given [key] with [t] */
+    /** Associates the specified [t] with the specified [key] in this [CreationExtras]. */
     public operator fun <T> set(key: Key<T>, t: T) {
-        map[key] = t
+        extras[key] = t
     }
 
-    public override fun <T> get(key: Key<T>): T? {
-        @Suppress("UNCHECKED_CAST") return map[key] as T?
-    }
+    /**
+     * Returns the value to which the specified [key] is associated, or null if this
+     * [CreationExtras] contains no mapping for the key.
+     */
+    @Suppress("UNCHECKED_CAST") public override fun <T> get(key: Key<T>): T? = extras[key] as T?
+}
+
+/**
+ * Checks if the [CreationExtras] contains the given [key].
+ *
+ * This method allows to use the `key in creationExtras` syntax for checking whether an [key] is
+ * contained in the [CreationExtras].
+ */
+public operator fun CreationExtras.contains(key: Key<*>): Boolean = key in extras
+
+/**
+ * Creates a new read-only [CreationExtras] by replacing or adding entries to [this] extras from
+ * another [creationExtras].
+ *
+ * The returned [CreationExtras] preserves the entry iteration order of the original
+ * [CreationExtras].
+ *
+ * Those entries of another [creationExtras] that are missing in [this] extras are iterated in the
+ * end in the order of that [creationExtras].
+ */
+public operator fun CreationExtras.plus(creationExtras: CreationExtras): MutableCreationExtras =
+    MutableCreationExtras(initialExtras = extras + creationExtras.extras)
+
+/** Appends or replaces all entries from the given [creationExtras] in [this] mutable extras. */
+public operator fun MutableCreationExtras.plusAssign(creationExtras: CreationExtras) {
+    extras += creationExtras.extras
 }