[go: nahoru, domu]

Merge "Add a hook that fires before the Activity's super.onCreate()" into androidx-master-dev
diff --git a/activity/activity/api/1.2.0-alpha07.txt b/activity/activity/api/1.2.0-alpha07.txt
index e2b5aed..6883231 100644
--- a/activity/activity/api/1.2.0-alpha07.txt
+++ b/activity/activity/api/1.2.0-alpha07.txt
@@ -1,9 +1,10 @@
 // Signature format: 3.0
 package androidx.activity {
 
-  public class ComponentActivity extends android.app.Activity implements androidx.activity.result.ActivityResultCaller androidx.activity.result.ActivityResultRegistryOwner androidx.lifecycle.HasDefaultViewModelProviderFactory androidx.lifecycle.LifecycleOwner androidx.activity.OnBackPressedDispatcherOwner androidx.savedstate.SavedStateRegistryOwner androidx.lifecycle.ViewModelStoreOwner {
+  public class ComponentActivity extends android.app.Activity implements androidx.activity.result.ActivityResultCaller androidx.activity.result.ActivityResultRegistryOwner androidx.activity.contextaware.ContextAware androidx.lifecycle.HasDefaultViewModelProviderFactory androidx.lifecycle.LifecycleOwner androidx.activity.OnBackPressedDispatcherOwner androidx.savedstate.SavedStateRegistryOwner androidx.lifecycle.ViewModelStoreOwner {
     ctor public ComponentActivity();
     ctor @ContentView public ComponentActivity(@LayoutRes int);
+    method public final void addOnContextAvailableListener(androidx.activity.contextaware.OnContextAvailableListener);
     method public final androidx.activity.result.ActivityResultRegistry getActivityResultRegistry();
     method public androidx.lifecycle.ViewModelProvider.Factory getDefaultViewModelProviderFactory();
     method @Deprecated public Object? getLastCustomNonConfigurationInstance();
@@ -17,6 +18,7 @@
     method public final Object? onRetainNonConfigurationInstance();
     method public final <I, O> androidx.activity.result.ActivityResultLauncher<I!> registerForActivityResult(androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultRegistry, androidx.activity.result.ActivityResultCallback<O!>);
     method public final <I, O> androidx.activity.result.ActivityResultLauncher<I!> registerForActivityResult(androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultCallback<O!>);
+    method public final void removeOnContextAvailableListener(androidx.activity.contextaware.OnContextAvailableListener);
     method @Deprecated public void startActivityForResult(android.content.Intent!, int);
     method @Deprecated public void startActivityForResult(android.content.Intent!, int, android.os.Bundle?);
     method @Deprecated public void startIntentSenderForResult(android.content.IntentSender!, int, android.content.Intent?, int, int, int) throws android.content.IntentSender.SendIntentException;
@@ -46,6 +48,26 @@
 
 }
 
+package androidx.activity.contextaware {
+
+  public interface ContextAware {
+    method public void addOnContextAvailableListener(androidx.activity.contextaware.OnContextAvailableListener);
+    method public void removeOnContextAvailableListener(androidx.activity.contextaware.OnContextAvailableListener);
+  }
+
+  public final class ContextAwareHelper {
+    ctor public ContextAwareHelper(androidx.activity.contextaware.ContextAware);
+    method public void addOnContextAvailableListener(androidx.activity.contextaware.OnContextAvailableListener);
+    method public void dispatchOnContextAvailable(android.content.Context, android.os.Bundle?);
+    method public void removeOnContextAvailableListener(androidx.activity.contextaware.OnContextAvailableListener);
+  }
+
+  public interface OnContextAvailableListener {
+    method public void onContextAvailable(androidx.activity.contextaware.ContextAware, android.content.Context, android.os.Bundle?);
+  }
+
+}
+
 package androidx.activity.result {
 
   public final class ActivityResult implements android.os.Parcelable {
diff --git a/activity/activity/api/current.txt b/activity/activity/api/current.txt
index e2b5aed..6883231 100644
--- a/activity/activity/api/current.txt
+++ b/activity/activity/api/current.txt
@@ -1,9 +1,10 @@
 // Signature format: 3.0
 package androidx.activity {
 
-  public class ComponentActivity extends android.app.Activity implements androidx.activity.result.ActivityResultCaller androidx.activity.result.ActivityResultRegistryOwner androidx.lifecycle.HasDefaultViewModelProviderFactory androidx.lifecycle.LifecycleOwner androidx.activity.OnBackPressedDispatcherOwner androidx.savedstate.SavedStateRegistryOwner androidx.lifecycle.ViewModelStoreOwner {
+  public class ComponentActivity extends android.app.Activity implements androidx.activity.result.ActivityResultCaller androidx.activity.result.ActivityResultRegistryOwner androidx.activity.contextaware.ContextAware androidx.lifecycle.HasDefaultViewModelProviderFactory androidx.lifecycle.LifecycleOwner androidx.activity.OnBackPressedDispatcherOwner androidx.savedstate.SavedStateRegistryOwner androidx.lifecycle.ViewModelStoreOwner {
     ctor public ComponentActivity();
     ctor @ContentView public ComponentActivity(@LayoutRes int);
+    method public final void addOnContextAvailableListener(androidx.activity.contextaware.OnContextAvailableListener);
     method public final androidx.activity.result.ActivityResultRegistry getActivityResultRegistry();
     method public androidx.lifecycle.ViewModelProvider.Factory getDefaultViewModelProviderFactory();
     method @Deprecated public Object? getLastCustomNonConfigurationInstance();
@@ -17,6 +18,7 @@
     method public final Object? onRetainNonConfigurationInstance();
     method public final <I, O> androidx.activity.result.ActivityResultLauncher<I!> registerForActivityResult(androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultRegistry, androidx.activity.result.ActivityResultCallback<O!>);
     method public final <I, O> androidx.activity.result.ActivityResultLauncher<I!> registerForActivityResult(androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultCallback<O!>);
+    method public final void removeOnContextAvailableListener(androidx.activity.contextaware.OnContextAvailableListener);
     method @Deprecated public void startActivityForResult(android.content.Intent!, int);
     method @Deprecated public void startActivityForResult(android.content.Intent!, int, android.os.Bundle?);
     method @Deprecated public void startIntentSenderForResult(android.content.IntentSender!, int, android.content.Intent?, int, int, int) throws android.content.IntentSender.SendIntentException;
@@ -46,6 +48,26 @@
 
 }
 
+package androidx.activity.contextaware {
+
+  public interface ContextAware {
+    method public void addOnContextAvailableListener(androidx.activity.contextaware.OnContextAvailableListener);
+    method public void removeOnContextAvailableListener(androidx.activity.contextaware.OnContextAvailableListener);
+  }
+
+  public final class ContextAwareHelper {
+    ctor public ContextAwareHelper(androidx.activity.contextaware.ContextAware);
+    method public void addOnContextAvailableListener(androidx.activity.contextaware.OnContextAvailableListener);
+    method public void dispatchOnContextAvailable(android.content.Context, android.os.Bundle?);
+    method public void removeOnContextAvailableListener(androidx.activity.contextaware.OnContextAvailableListener);
+  }
+
+  public interface OnContextAvailableListener {
+    method public void onContextAvailable(androidx.activity.contextaware.ContextAware, android.content.Context, android.os.Bundle?);
+  }
+
+}
+
 package androidx.activity.result {
 
   public final class ActivityResult implements android.os.Parcelable {
diff --git a/activity/activity/api/public_plus_experimental_1.2.0-alpha07.txt b/activity/activity/api/public_plus_experimental_1.2.0-alpha07.txt
index 1daf641..c40287f 100644
--- a/activity/activity/api/public_plus_experimental_1.2.0-alpha07.txt
+++ b/activity/activity/api/public_plus_experimental_1.2.0-alpha07.txt
@@ -1,9 +1,10 @@
 // Signature format: 3.0
 package androidx.activity {
 
-  public class ComponentActivity extends androidx.core.app.ComponentActivity implements androidx.activity.result.ActivityResultCaller androidx.activity.result.ActivityResultRegistryOwner androidx.lifecycle.HasDefaultViewModelProviderFactory androidx.lifecycle.LifecycleOwner androidx.activity.OnBackPressedDispatcherOwner androidx.savedstate.SavedStateRegistryOwner androidx.lifecycle.ViewModelStoreOwner {
+  public class ComponentActivity extends androidx.core.app.ComponentActivity implements androidx.activity.result.ActivityResultCaller androidx.activity.result.ActivityResultRegistryOwner androidx.activity.contextaware.ContextAware androidx.lifecycle.HasDefaultViewModelProviderFactory androidx.lifecycle.LifecycleOwner androidx.activity.OnBackPressedDispatcherOwner androidx.savedstate.SavedStateRegistryOwner androidx.lifecycle.ViewModelStoreOwner {
     ctor public ComponentActivity();
     ctor @ContentView public ComponentActivity(@LayoutRes int);
+    method public final void addOnContextAvailableListener(androidx.activity.contextaware.OnContextAvailableListener);
     method public final androidx.activity.result.ActivityResultRegistry getActivityResultRegistry();
     method public androidx.lifecycle.ViewModelProvider.Factory getDefaultViewModelProviderFactory();
     method @Deprecated public Object? getLastCustomNonConfigurationInstance();
@@ -16,6 +17,7 @@
     method public final Object? onRetainNonConfigurationInstance();
     method public final <I, O> androidx.activity.result.ActivityResultLauncher<I!> registerForActivityResult(androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultRegistry, androidx.activity.result.ActivityResultCallback<O!>);
     method public final <I, O> androidx.activity.result.ActivityResultLauncher<I!> registerForActivityResult(androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultCallback<O!>);
+    method public final void removeOnContextAvailableListener(androidx.activity.contextaware.OnContextAvailableListener);
     method @Deprecated public void startActivityForResult(android.content.Intent!, int);
     method @Deprecated public void startActivityForResult(android.content.Intent!, int, android.os.Bundle?);
     method @Deprecated public void startIntentSenderForResult(android.content.IntentSender!, int, android.content.Intent?, int, int, int) throws android.content.IntentSender.SendIntentException;
@@ -45,6 +47,26 @@
 
 }
 
+package androidx.activity.contextaware {
+
+  public interface ContextAware {
+    method public void addOnContextAvailableListener(androidx.activity.contextaware.OnContextAvailableListener);
+    method public void removeOnContextAvailableListener(androidx.activity.contextaware.OnContextAvailableListener);
+  }
+
+  public final class ContextAwareHelper {
+    ctor public ContextAwareHelper(androidx.activity.contextaware.ContextAware);
+    method public void addOnContextAvailableListener(androidx.activity.contextaware.OnContextAvailableListener);
+    method public void dispatchOnContextAvailable(android.content.Context, android.os.Bundle?);
+    method public void removeOnContextAvailableListener(androidx.activity.contextaware.OnContextAvailableListener);
+  }
+
+  public interface OnContextAvailableListener {
+    method public void onContextAvailable(androidx.activity.contextaware.ContextAware, android.content.Context, android.os.Bundle?);
+  }
+
+}
+
 package androidx.activity.result {
 
   public final class ActivityResult implements android.os.Parcelable {
diff --git a/activity/activity/api/public_plus_experimental_current.txt b/activity/activity/api/public_plus_experimental_current.txt
index 1daf641..c40287f 100644
--- a/activity/activity/api/public_plus_experimental_current.txt
+++ b/activity/activity/api/public_plus_experimental_current.txt
@@ -1,9 +1,10 @@
 // Signature format: 3.0
 package androidx.activity {
 
-  public class ComponentActivity extends androidx.core.app.ComponentActivity implements androidx.activity.result.ActivityResultCaller androidx.activity.result.ActivityResultRegistryOwner androidx.lifecycle.HasDefaultViewModelProviderFactory androidx.lifecycle.LifecycleOwner androidx.activity.OnBackPressedDispatcherOwner androidx.savedstate.SavedStateRegistryOwner androidx.lifecycle.ViewModelStoreOwner {
+  public class ComponentActivity extends androidx.core.app.ComponentActivity implements androidx.activity.result.ActivityResultCaller androidx.activity.result.ActivityResultRegistryOwner androidx.activity.contextaware.ContextAware androidx.lifecycle.HasDefaultViewModelProviderFactory androidx.lifecycle.LifecycleOwner androidx.activity.OnBackPressedDispatcherOwner androidx.savedstate.SavedStateRegistryOwner androidx.lifecycle.ViewModelStoreOwner {
     ctor public ComponentActivity();
     ctor @ContentView public ComponentActivity(@LayoutRes int);
+    method public final void addOnContextAvailableListener(androidx.activity.contextaware.OnContextAvailableListener);
     method public final androidx.activity.result.ActivityResultRegistry getActivityResultRegistry();
     method public androidx.lifecycle.ViewModelProvider.Factory getDefaultViewModelProviderFactory();
     method @Deprecated public Object? getLastCustomNonConfigurationInstance();
@@ -16,6 +17,7 @@
     method public final Object? onRetainNonConfigurationInstance();
     method public final <I, O> androidx.activity.result.ActivityResultLauncher<I!> registerForActivityResult(androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultRegistry, androidx.activity.result.ActivityResultCallback<O!>);
     method public final <I, O> androidx.activity.result.ActivityResultLauncher<I!> registerForActivityResult(androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultCallback<O!>);
+    method public final void removeOnContextAvailableListener(androidx.activity.contextaware.OnContextAvailableListener);
     method @Deprecated public void startActivityForResult(android.content.Intent!, int);
     method @Deprecated public void startActivityForResult(android.content.Intent!, int, android.os.Bundle?);
     method @Deprecated public void startIntentSenderForResult(android.content.IntentSender!, int, android.content.Intent?, int, int, int) throws android.content.IntentSender.SendIntentException;
@@ -45,6 +47,26 @@
 
 }
 
+package androidx.activity.contextaware {
+
+  public interface ContextAware {
+    method public void addOnContextAvailableListener(androidx.activity.contextaware.OnContextAvailableListener);
+    method public void removeOnContextAvailableListener(androidx.activity.contextaware.OnContextAvailableListener);
+  }
+
+  public final class ContextAwareHelper {
+    ctor public ContextAwareHelper(androidx.activity.contextaware.ContextAware);
+    method public void addOnContextAvailableListener(androidx.activity.contextaware.OnContextAvailableListener);
+    method public void dispatchOnContextAvailable(android.content.Context, android.os.Bundle?);
+    method public void removeOnContextAvailableListener(androidx.activity.contextaware.OnContextAvailableListener);
+  }
+
+  public interface OnContextAvailableListener {
+    method public void onContextAvailable(androidx.activity.contextaware.ContextAware, android.content.Context, android.os.Bundle?);
+  }
+
+}
+
 package androidx.activity.result {
 
   public final class ActivityResult implements android.os.Parcelable {
diff --git a/activity/activity/api/restricted_1.2.0-alpha07.txt b/activity/activity/api/restricted_1.2.0-alpha07.txt
index 1daf641..c40287f 100644
--- a/activity/activity/api/restricted_1.2.0-alpha07.txt
+++ b/activity/activity/api/restricted_1.2.0-alpha07.txt
@@ -1,9 +1,10 @@
 // Signature format: 3.0
 package androidx.activity {
 
-  public class ComponentActivity extends androidx.core.app.ComponentActivity implements androidx.activity.result.ActivityResultCaller androidx.activity.result.ActivityResultRegistryOwner androidx.lifecycle.HasDefaultViewModelProviderFactory androidx.lifecycle.LifecycleOwner androidx.activity.OnBackPressedDispatcherOwner androidx.savedstate.SavedStateRegistryOwner androidx.lifecycle.ViewModelStoreOwner {
+  public class ComponentActivity extends androidx.core.app.ComponentActivity implements androidx.activity.result.ActivityResultCaller androidx.activity.result.ActivityResultRegistryOwner androidx.activity.contextaware.ContextAware androidx.lifecycle.HasDefaultViewModelProviderFactory androidx.lifecycle.LifecycleOwner androidx.activity.OnBackPressedDispatcherOwner androidx.savedstate.SavedStateRegistryOwner androidx.lifecycle.ViewModelStoreOwner {
     ctor public ComponentActivity();
     ctor @ContentView public ComponentActivity(@LayoutRes int);
+    method public final void addOnContextAvailableListener(androidx.activity.contextaware.OnContextAvailableListener);
     method public final androidx.activity.result.ActivityResultRegistry getActivityResultRegistry();
     method public androidx.lifecycle.ViewModelProvider.Factory getDefaultViewModelProviderFactory();
     method @Deprecated public Object? getLastCustomNonConfigurationInstance();
@@ -16,6 +17,7 @@
     method public final Object? onRetainNonConfigurationInstance();
     method public final <I, O> androidx.activity.result.ActivityResultLauncher<I!> registerForActivityResult(androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultRegistry, androidx.activity.result.ActivityResultCallback<O!>);
     method public final <I, O> androidx.activity.result.ActivityResultLauncher<I!> registerForActivityResult(androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultCallback<O!>);
+    method public final void removeOnContextAvailableListener(androidx.activity.contextaware.OnContextAvailableListener);
     method @Deprecated public void startActivityForResult(android.content.Intent!, int);
     method @Deprecated public void startActivityForResult(android.content.Intent!, int, android.os.Bundle?);
     method @Deprecated public void startIntentSenderForResult(android.content.IntentSender!, int, android.content.Intent?, int, int, int) throws android.content.IntentSender.SendIntentException;
@@ -45,6 +47,26 @@
 
 }
 
+package androidx.activity.contextaware {
+
+  public interface ContextAware {
+    method public void addOnContextAvailableListener(androidx.activity.contextaware.OnContextAvailableListener);
+    method public void removeOnContextAvailableListener(androidx.activity.contextaware.OnContextAvailableListener);
+  }
+
+  public final class ContextAwareHelper {
+    ctor public ContextAwareHelper(androidx.activity.contextaware.ContextAware);
+    method public void addOnContextAvailableListener(androidx.activity.contextaware.OnContextAvailableListener);
+    method public void dispatchOnContextAvailable(android.content.Context, android.os.Bundle?);
+    method public void removeOnContextAvailableListener(androidx.activity.contextaware.OnContextAvailableListener);
+  }
+
+  public interface OnContextAvailableListener {
+    method public void onContextAvailable(androidx.activity.contextaware.ContextAware, android.content.Context, android.os.Bundle?);
+  }
+
+}
+
 package androidx.activity.result {
 
   public final class ActivityResult implements android.os.Parcelable {
diff --git a/activity/activity/api/restricted_current.txt b/activity/activity/api/restricted_current.txt
index 1daf641..c40287f 100644
--- a/activity/activity/api/restricted_current.txt
+++ b/activity/activity/api/restricted_current.txt
@@ -1,9 +1,10 @@
 // Signature format: 3.0
 package androidx.activity {
 
-  public class ComponentActivity extends androidx.core.app.ComponentActivity implements androidx.activity.result.ActivityResultCaller androidx.activity.result.ActivityResultRegistryOwner androidx.lifecycle.HasDefaultViewModelProviderFactory androidx.lifecycle.LifecycleOwner androidx.activity.OnBackPressedDispatcherOwner androidx.savedstate.SavedStateRegistryOwner androidx.lifecycle.ViewModelStoreOwner {
+  public class ComponentActivity extends androidx.core.app.ComponentActivity implements androidx.activity.result.ActivityResultCaller androidx.activity.result.ActivityResultRegistryOwner androidx.activity.contextaware.ContextAware androidx.lifecycle.HasDefaultViewModelProviderFactory androidx.lifecycle.LifecycleOwner androidx.activity.OnBackPressedDispatcherOwner androidx.savedstate.SavedStateRegistryOwner androidx.lifecycle.ViewModelStoreOwner {
     ctor public ComponentActivity();
     ctor @ContentView public ComponentActivity(@LayoutRes int);
+    method public final void addOnContextAvailableListener(androidx.activity.contextaware.OnContextAvailableListener);
     method public final androidx.activity.result.ActivityResultRegistry getActivityResultRegistry();
     method public androidx.lifecycle.ViewModelProvider.Factory getDefaultViewModelProviderFactory();
     method @Deprecated public Object? getLastCustomNonConfigurationInstance();
@@ -16,6 +17,7 @@
     method public final Object? onRetainNonConfigurationInstance();
     method public final <I, O> androidx.activity.result.ActivityResultLauncher<I!> registerForActivityResult(androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultRegistry, androidx.activity.result.ActivityResultCallback<O!>);
     method public final <I, O> androidx.activity.result.ActivityResultLauncher<I!> registerForActivityResult(androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultCallback<O!>);
+    method public final void removeOnContextAvailableListener(androidx.activity.contextaware.OnContextAvailableListener);
     method @Deprecated public void startActivityForResult(android.content.Intent!, int);
     method @Deprecated public void startActivityForResult(android.content.Intent!, int, android.os.Bundle?);
     method @Deprecated public void startIntentSenderForResult(android.content.IntentSender!, int, android.content.Intent?, int, int, int) throws android.content.IntentSender.SendIntentException;
@@ -45,6 +47,26 @@
 
 }
 
+package androidx.activity.contextaware {
+
+  public interface ContextAware {
+    method public void addOnContextAvailableListener(androidx.activity.contextaware.OnContextAvailableListener);
+    method public void removeOnContextAvailableListener(androidx.activity.contextaware.OnContextAvailableListener);
+  }
+
+  public final class ContextAwareHelper {
+    ctor public ContextAwareHelper(androidx.activity.contextaware.ContextAware);
+    method public void addOnContextAvailableListener(androidx.activity.contextaware.OnContextAvailableListener);
+    method public void dispatchOnContextAvailable(android.content.Context, android.os.Bundle?);
+    method public void removeOnContextAvailableListener(androidx.activity.contextaware.OnContextAvailableListener);
+  }
+
+  public interface OnContextAvailableListener {
+    method public void onContextAvailable(androidx.activity.contextaware.ContextAware, android.content.Context, android.os.Bundle?);
+  }
+
+}
+
 package androidx.activity.result {
 
   public final class ActivityResult implements android.os.Parcelable {
diff --git a/activity/activity/src/androidTest/java/androidx/activity/ComponentActivityLifecycleTest.kt b/activity/activity/src/androidTest/java/androidx/activity/ComponentActivityLifecycleTest.kt
index 09de5e3..d8ac2bf 100644
--- a/activity/activity/src/androidTest/java/androidx/activity/ComponentActivityLifecycleTest.kt
+++ b/activity/activity/src/androidTest/java/androidx/activity/ComponentActivityLifecycleTest.kt
@@ -28,6 +28,7 @@
 import org.junit.runner.RunWith
 
 internal enum class LifecycleSource {
+    CONTEXT_AWARE,
     ACTIVITY,
     ACTIVITY_CALLBACK
 }
@@ -48,6 +49,7 @@
         // followed by the activity's lifecycle observers
         assertThat(events)
             .containsExactly(
+                LifecycleSource.CONTEXT_AWARE to Lifecycle.Event.ON_CREATE,
                 LifecycleSource.ACTIVITY_CALLBACK to Lifecycle.Event.ON_CREATE,
                 LifecycleSource.ACTIVITY to Lifecycle.Event.ON_CREATE,
                 LifecycleSource.ACTIVITY_CALLBACK to Lifecycle.Event.ON_START,
@@ -69,6 +71,9 @@
     internal val events = mutableListOf<Pair<LifecycleSource, Lifecycle.Event>>()
 
     init {
+        addOnContextAvailableListener { _, _, _ ->
+            events.add(LifecycleSource.CONTEXT_AWARE to Lifecycle.Event.ON_CREATE)
+        }
         lifecycle.addObserver(LifecycleEventObserver { _, event ->
             events.add(LifecycleSource.ACTIVITY to event)
         })
diff --git a/activity/activity/src/androidTest/java/androidx/activity/contextaware/ContextAwareHelperTest.kt b/activity/activity/src/androidTest/java/androidx/activity/contextaware/ContextAwareHelperTest.kt
new file mode 100644
index 0000000..3087989
--- /dev/null
+++ b/activity/activity/src/androidTest/java/androidx/activity/contextaware/ContextAwareHelperTest.kt
@@ -0,0 +1,103 @@
+/*
+ * 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.activity.contextaware
+
+import android.content.Context
+import android.os.Bundle
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class ContextAwareHelperTest {
+    private val contextAware = TestContextAware()
+
+    @Test
+    fun addOnContextAvailableListener() {
+        var receivedContextAware: ContextAware? = null
+        val listener = OnContextAvailableListener { contextAware, _, _ ->
+            receivedContextAware = contextAware
+        }
+        contextAware.addOnContextAvailableListener(listener)
+        contextAware.dispatchOnContextAvailable()
+
+        assertThat(receivedContextAware).isSameInstanceAs(contextAware)
+    }
+
+    @Test
+    fun removeOnContextAvailableListener() {
+        var callbackCount = 0
+        val listener = OnContextAvailableListener { _, _, _ ->
+            callbackCount++
+        }
+        contextAware.addOnContextAvailableListener(listener)
+        contextAware.dispatchOnContextAvailable()
+
+        assertThat(callbackCount).isEqualTo(1)
+
+        // Now remove the listener and check that the count doesn't increase
+        contextAware.removeOnContextAvailableListener(listener)
+        contextAware.dispatchOnContextAvailable()
+
+        assertThat(callbackCount).isEqualTo(1)
+    }
+
+    @Test
+    fun reentrantRemove() {
+        var callbackCount = 0
+        val listener = object : OnContextAvailableListener {
+            override fun onContextAvailable(
+                contextAware: ContextAware,
+                context: Context,
+                savedInstanceState: Bundle?
+            ) {
+                callbackCount++
+                contextAware.removeOnContextAvailableListener(this)
+            }
+        }
+        contextAware.addOnContextAvailableListener(listener)
+        contextAware.dispatchOnContextAvailable()
+
+        assertThat(callbackCount).isEqualTo(1)
+
+        callbackCount = 0
+        contextAware.dispatchOnContextAvailable()
+
+        assertThat(callbackCount).isEqualTo(0)
+    }
+}
+
+class TestContextAware : ContextAware {
+    private val contextAwareHelper = ContextAwareHelper(this)
+
+    override fun addOnContextAvailableListener(listener: OnContextAvailableListener) {
+        contextAwareHelper.addOnContextAvailableListener(listener)
+    }
+
+    override fun removeOnContextAvailableListener(listener: OnContextAvailableListener) {
+        contextAwareHelper.removeOnContextAvailableListener(listener)
+    }
+
+    fun dispatchOnContextAvailable(savedInstanceState: Bundle? = null) {
+        contextAwareHelper.dispatchOnContextAvailable(
+            ApplicationProvider.getApplicationContext(), savedInstanceState)
+    }
+}
\ No newline at end of file
diff --git a/activity/activity/src/main/java/androidx/activity/ComponentActivity.java b/activity/activity/src/main/java/androidx/activity/ComponentActivity.java
index 24a4863..60ddd6b 100644
--- a/activity/activity/src/main/java/androidx/activity/ComponentActivity.java
+++ b/activity/activity/src/main/java/androidx/activity/ComponentActivity.java
@@ -43,6 +43,9 @@
 import android.view.ViewGroup;
 import android.view.Window;
 
+import androidx.activity.contextaware.ContextAware;
+import androidx.activity.contextaware.ContextAwareHelper;
+import androidx.activity.contextaware.OnContextAvailableListener;
 import androidx.activity.result.ActivityResultCallback;
 import androidx.activity.result.ActivityResultCaller;
 import androidx.activity.result.ActivityResultLauncher;
@@ -87,6 +90,7 @@
  * without enforcing a deep Activity class hierarchy or strong coupling between components.
  */
 public class ComponentActivity extends androidx.core.app.ComponentActivity implements
+        ContextAware,
         LifecycleOwner,
         ViewModelStoreOwner,
         HasDefaultViewModelProviderFactory,
@@ -100,6 +104,7 @@
         ViewModelStore viewModelStore;
     }
 
+    private final ContextAwareHelper mContextAwareHelper = new ContextAwareHelper(this);
     private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
     private final SavedStateRegistryController mSavedStateRegistryController =
             SavedStateRegistryController.create(this);
@@ -279,6 +284,7 @@
      */
     @Override
     protected void onCreate(@Nullable Bundle savedInstanceState) {
+        mContextAwareHelper.dispatchOnContextAvailable(this, savedInstanceState);
         super.onCreate(savedInstanceState);
         mSavedStateRegistryController.performRestore(savedInstanceState);
         mActivityResultRegistry.onRestoreInstanceState(savedInstanceState);
@@ -397,6 +403,26 @@
 
     /**
      * {@inheritDoc}
+     *
+     * Any listener added here will receive a callback as part of
+     * <code>super.onCreate()</code>, but importantly <strong>before</strong> any other
+     * logic is done (including calling through to the framework
+     * {@link Activity#onCreate(Bundle)}.
+     */
+    @Override
+    public final void addOnContextAvailableListener(
+            @NonNull OnContextAvailableListener listener) {
+        mContextAwareHelper.addOnContextAvailableListener(listener);
+    }
+
+    @Override
+    public final void removeOnContextAvailableListener(
+            @NonNull OnContextAvailableListener listener) {
+        mContextAwareHelper.removeOnContextAvailableListener(listener);
+    }
+
+    /**
+     * {@inheritDoc}
      * <p>
      * Overriding this method is no longer supported and this method will be made
      * <code>final</code> in a future version of ComponentActivity. If you do override
diff --git a/activity/activity/src/main/java/androidx/activity/contextaware/ContextAware.java b/activity/activity/src/main/java/androidx/activity/contextaware/ContextAware.java
new file mode 100644
index 0000000..a8dde12
--- /dev/null
+++ b/activity/activity/src/main/java/androidx/activity/contextaware/ContextAware.java
@@ -0,0 +1,49 @@
+/*
+ * 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.activity.contextaware;
+
+import androidx.annotation.NonNull;
+
+/**
+ * A <code>ContextAware</code> class is associated with a {@link android.content.Context} as
+ * a part of its lifecycle.
+ *
+ * @see ContextAwareHelper
+ */
+public interface ContextAware {
+
+    /**
+     * Add a new {@link OnContextAvailableListener} for receiving a callback for when
+     * this class is associated with a {@link android.content.Context}.
+     * <p>
+     * This will only receive a callback when associated with a new Context: no callback
+     * will be triggered if this is already associated with a Context.
+     *
+     * @param listener The listener that should be added.
+     * @see #removeOnContextAvailableListener(OnContextAvailableListener)
+     */
+    void addOnContextAvailableListener(@NonNull OnContextAvailableListener listener);
+
+    /**
+     * Remove a {@link OnContextAvailableListener} previously added via
+     * {@link #addOnContextAvailableListener(OnContextAvailableListener)}.
+     *
+     * @param listener The listener that should be removed.
+     * @see #addOnContextAvailableListener(OnContextAvailableListener)
+     */
+    void removeOnContextAvailableListener(@NonNull OnContextAvailableListener listener);
+}
diff --git a/activity/activity/src/main/java/androidx/activity/contextaware/ContextAwareHelper.java b/activity/activity/src/main/java/androidx/activity/contextaware/ContextAwareHelper.java
new file mode 100644
index 0000000..3e21c20
--- /dev/null
+++ b/activity/activity/src/main/java/androidx/activity/contextaware/ContextAwareHelper.java
@@ -0,0 +1,87 @@
+/*
+ * 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.activity.contextaware;
+
+import android.content.Context;
+import android.os.Bundle;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import java.util.Set;
+import java.util.concurrent.CopyOnWriteArraySet;
+
+/**
+ * Helper class for implementing {@link ContextAware}. Classes using this helper should
+ * call {@link #addOnContextAvailableListener(OnContextAvailableListener)} and
+ * {@link #removeOnContextAvailableListener(OnContextAvailableListener)} as the respective
+ * methods of {@link ContextAware} are called.
+ * <p>
+ * You must call {@link #dispatchOnContextAvailable(Context, Bundle)} once the
+ * {@link Context} is available to dispatch the callbacks to all registered listeners.
+ */
+public final class ContextAwareHelper {
+
+    private final ContextAware mContextAware;
+
+    private final Set<OnContextAvailableListener> mListeners = new CopyOnWriteArraySet<>();
+
+    /**
+     * Construct a new ContextAwareHelper for the given {@link ContextAware} instance.
+     *
+     * @param contextAware The ContextAware instance that listeners are being added to.
+     */
+    public ContextAwareHelper(@NonNull ContextAware contextAware) {
+        mContextAware = contextAware;
+    }
+
+    /**
+     * Add a new {@link OnContextAvailableListener} for receiving a callback for when
+     * this class is associated with a {@link android.content.Context}.
+     *
+     * @param listener The listener that should be added.
+     * @see #removeOnContextAvailableListener(OnContextAvailableListener)
+     */
+    public void addOnContextAvailableListener(@NonNull OnContextAvailableListener listener) {
+        mListeners.add(listener);
+    }
+
+    /**
+     * Remove a {@link OnContextAvailableListener} previously added via
+     * {@link #addOnContextAvailableListener(OnContextAvailableListener)}.
+     *
+     * @param listener The listener that should be removed.
+     * @see #addOnContextAvailableListener(OnContextAvailableListener)
+     */
+    public void removeOnContextAvailableListener(@NonNull OnContextAvailableListener listener) {
+        mListeners.remove(listener);
+    }
+
+    /**
+     * Dispatch the callback of {@link OnContextAvailableListener#onContextAvailable} to
+     * all currently added listeners.
+     *
+     * @param context The {@link Context} the {@link ContextAware} object is now associated with.
+     * @param savedInstanceState The saved instance state, if any.
+     */
+    public void dispatchOnContextAvailable(@NonNull Context context,
+            @Nullable Bundle savedInstanceState) {
+        for (OnContextAvailableListener listener : mListeners) {
+            listener.onContextAvailable(mContextAware, context, savedInstanceState);
+        }
+    }
+}
diff --git a/activity/activity/src/main/java/androidx/activity/contextaware/OnContextAvailableListener.java b/activity/activity/src/main/java/androidx/activity/contextaware/OnContextAvailableListener.java
new file mode 100644
index 0000000..00614a2
--- /dev/null
+++ b/activity/activity/src/main/java/androidx/activity/contextaware/OnContextAvailableListener.java
@@ -0,0 +1,45 @@
+/*
+ * 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.activity.contextaware;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.os.Bundle;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+/**
+ * Listener for receiving a callback at the first moment a {@link Context} is made
+ * available to the {@link ContextAware} class.
+ *
+ * @see ContextAware#addOnContextAvailableListener(OnContextAvailableListener)
+ */
+public interface OnContextAvailableListener {
+
+    /**
+     * Called when the given {@link ContextAware} object is associated to a {@link Context}.
+     *
+     * @param contextAware The object that this listener for added to.
+     * @param context The {@link Context} the {@link ContextAware} object is now associated with.
+     * @param savedInstanceState The saved instance state, if any.
+     */
+    void onContextAvailable(@NonNull ContextAware contextAware,
+            @SuppressLint("ContextFirst") /* The object being operated on should be first */
+            @NonNull Context context,
+            @Nullable Bundle savedInstanceState);
+}
diff --git a/appcompat/appcompat/build.gradle b/appcompat/appcompat/build.gradle
index bdd7054..1afec62 100644
--- a/appcompat/appcompat/build.gradle
+++ b/appcompat/appcompat/build.gradle
@@ -15,7 +15,10 @@
     api(project(":core:core"))
     implementation("androidx.collection:collection:1.0.0")
     api("androidx.cursoradapter:cursoradapter:1.0.0")
-    api("androidx.fragment:fragment:1.1.0")
+    api(project(":activity:activity"))
+    // Activity 1.2 requires depending on Fragment 1.3, so we need project dependencies on both
+    // despite only directly requiring new APIs in Activity 1.2
+    api(project(":fragment:fragment"))
     api(project(":appcompat:appcompat-resources"))
     api("androidx.drawerlayout:drawerlayout:1.0.0")
     implementation(project(":lifecycle:lifecycle-runtime"))
diff --git a/appcompat/appcompat/src/main/java/androidx/appcompat/app/AppCompatActivity.java b/appcompat/appcompat/src/main/java/androidx/appcompat/app/AppCompatActivity.java
index 664d69f..8c35ee4 100644
--- a/appcompat/appcompat/src/main/java/androidx/appcompat/app/AppCompatActivity.java
+++ b/appcompat/appcompat/src/main/java/androidx/appcompat/app/AppCompatActivity.java
@@ -30,6 +30,8 @@
 import android.view.ViewGroup;
 import android.view.Window;
 
+import androidx.activity.contextaware.ContextAware;
+import androidx.activity.contextaware.OnContextAvailableListener;
 import androidx.annotation.CallSuper;
 import androidx.annotation.ContentView;
 import androidx.annotation.IdRes;
@@ -88,6 +90,7 @@
      */
     public AppCompatActivity() {
         super();
+        initDelegate();
     }
 
     /**
@@ -103,6 +106,19 @@
     @ContentView
     public AppCompatActivity(@LayoutRes int contentLayoutId) {
         super(contentLayoutId);
+        initDelegate();
+    }
+
+    private void initDelegate() {
+        addOnContextAvailableListener(new OnContextAvailableListener() {
+            @Override
+            public void onContextAvailable(@NonNull ContextAware contextAware,
+                    @NonNull Context context, @Nullable Bundle savedInstanceState) {
+                final AppCompatDelegate delegate = getDelegate();
+                delegate.installViewFactory();
+                delegate.onCreate(savedInstanceState);
+            }
+        });
     }
 
     @Override
@@ -111,14 +127,6 @@
     }
 
     @Override
-    protected void onCreate(@Nullable Bundle savedInstanceState) {
-        final AppCompatDelegate delegate = getDelegate();
-        delegate.installViewFactory();
-        delegate.onCreate(savedInstanceState);
-        super.onCreate(savedInstanceState);
-    }
-
-    @Override
     public void setTheme(@StyleRes final int resId) {
         super.setTheme(resId);
         getDelegate().setTheme(resId);
diff --git a/fragment/fragment/src/main/java/androidx/fragment/app/FragmentActivity.java b/fragment/fragment/src/main/java/androidx/fragment/app/FragmentActivity.java
index 8085a9c..0c1a46a 100644
--- a/fragment/fragment/src/main/java/androidx/fragment/app/FragmentActivity.java
+++ b/fragment/fragment/src/main/java/androidx/fragment/app/FragmentActivity.java
@@ -38,6 +38,8 @@
 import androidx.activity.ComponentActivity;
 import androidx.activity.OnBackPressedDispatcher;
 import androidx.activity.OnBackPressedDispatcherOwner;
+import androidx.activity.contextaware.ContextAware;
+import androidx.activity.contextaware.OnContextAvailableListener;
 import androidx.activity.result.ActivityResultCallback;
 import androidx.activity.result.ActivityResultRegistry;
 import androidx.activity.result.ActivityResultRegistryOwner;
@@ -99,6 +101,7 @@
      */
     public FragmentActivity() {
         super();
+        init();
     }
 
     /**
@@ -114,6 +117,22 @@
     @ContentView
     public FragmentActivity(@LayoutRes int contentLayoutId) {
         super(contentLayoutId);
+        init();
+    }
+
+    private void init() {
+        addOnContextAvailableListener(new OnContextAvailableListener() {
+            @Override
+            public void onContextAvailable(@NonNull ContextAware contextAware,
+                    @NonNull Context context, @Nullable Bundle savedInstanceState) {
+                mFragments.attachHost(null /*parent*/);
+
+                if (savedInstanceState != null) {
+                    Parcelable p = savedInstanceState.getParcelable(FRAGMENTS_TAG);
+                    mFragments.restoreSaveState(p);
+                }
+            }
+        });
     }
 
     // ------------------------------------------------------------------------
@@ -230,13 +249,6 @@
      */
     @Override
     protected void onCreate(@Nullable Bundle savedInstanceState) {
-        mFragments.attachHost(null /*parent*/);
-
-        if (savedInstanceState != null) {
-            Parcelable p = savedInstanceState.getParcelable(FRAGMENTS_TAG);
-            mFragments.restoreSaveState(p);
-        }
-
         super.onCreate(savedInstanceState);
 
         mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);